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 #ifndef CHROME_BROWSER_BROWSING_DATA_COOKIES_TREE_MODEL_H_
6 #define CHROME_BROWSER_BROWSING_DATA_COOKIES_TREE_MODEL_H_
7 
8 #include <list>
9 #include <memory>
10 #include <string>
11 #include <vector>
12 
13 #include "base/macros.h"
14 #include "base/observer_list.h"
15 #include "base/strings/string16.h"
16 #include "build/build_config.h"
17 #include "chrome/browser/browsing_data/local_data_container.h"
18 #include "components/content_settings/core/common/content_settings.h"
19 #include "extensions/buildflags/buildflags.h"
20 #include "ui/base/models/tree_node_model.h"
21 
22 #if !defined(OS_ANDROID)
23 #include "chrome/browser/browsing_data/access_context_audit_database.h"
24 #endif  // !defined(OS_ANDROID)
25 
26 class AccessContextAuditService;
27 class CookiesTreeModel;
28 class CookieTreeAppCacheNode;
29 class CookieTreeAppCachesNode;
30 class CookieTreeCacheStorageNode;
31 class CookieTreeCacheStoragesNode;
32 class CookieTreeCookieNode;
33 class CookieTreeCookiesNode;
34 class CookieTreeDatabaseNode;
35 class CookieTreeDatabasesNode;
36 class CookieTreeFileSystemNode;
37 class CookieTreeFileSystemsNode;
38 class CookieTreeHostNode;
39 class CookieTreeIndexedDBNode;
40 class CookieTreeIndexedDBsNode;
41 class CookieTreeLocalStorageNode;
42 class CookieTreeLocalStoragesNode;
43 class CookieTreeMediaLicenseNode;
44 class CookieTreeMediaLicensesNode;
45 class CookieTreeQuotaNode;
46 class CookieTreeServiceWorkerNode;
47 class CookieTreeServiceWorkersNode;
48 class CookieTreeSharedWorkerNode;
49 class CookieTreeSharedWorkersNode;
50 class CookieTreeSessionStorageNode;
51 class CookieTreeSessionStoragesNode;
52 class ExtensionSpecialStoragePolicy;
53 
54 namespace content_settings {
55 class CookieSettings;
56 }
57 
58 namespace extensions {
59 class ExtensionSet;
60 }
61 
62 namespace net {
63 class CanonicalCookie;
64 }
65 
66 // CookieTreeNode -------------------------------------------------------------
67 // The base node type in the Cookies, Databases, and Local Storage options
68 // view, from which all other types are derived. Specialized from TreeNode in
69 // that it has a notion of deleting objects stored in the profile, and being
70 // able to have its children do the same.
71 class CookieTreeNode : public ui::TreeNode<CookieTreeNode> {
72  public:
73   // Used to pull out information for the InfoView (the details display below
74   // the tree control.)
75   struct DetailedInfo {
76     // NodeType corresponds to the various CookieTreeNode types.
77     enum NodeType {
78       TYPE_NONE,
79       TYPE_ROOT,              // This is used for CookieTreeRootNode nodes.
80       TYPE_HOST,              // This is used for CookieTreeHostNode nodes.
81       TYPE_COOKIES,           // This is used for CookieTreeCookiesNode nodes.
82       TYPE_COOKIE,            // This is used for CookieTreeCookieNode nodes.
83       TYPE_DATABASES,         // This is used for CookieTreeDatabasesNode.
84       TYPE_DATABASE,          // This is used for CookieTreeDatabaseNode.
85       TYPE_LOCAL_STORAGES,    // This is used for CookieTreeLocalStoragesNode.
86       TYPE_LOCAL_STORAGE,     // This is used for CookieTreeLocalStorageNode.
87       TYPE_SESSION_STORAGES,  // This is used for CookieTreeSessionStoragesNode.
88       TYPE_SESSION_STORAGE,   // This is used for CookieTreeSessionStorageNode.
89       TYPE_APPCACHES,         // This is used for CookieTreeAppCachesNode.
90       TYPE_APPCACHE,          // This is used for CookieTreeAppCacheNode.
91       TYPE_INDEXED_DBS,       // This is used for CookieTreeIndexedDBsNode.
92       TYPE_INDEXED_DB,        // This is used for CookieTreeIndexedDBNode.
93       TYPE_FILE_SYSTEMS,      // This is used for CookieTreeFileSystemsNode.
94       TYPE_FILE_SYSTEM,       // This is used for CookieTreeFileSystemNode.
95       TYPE_QUOTA,             // This is used for CookieTreeQuotaNode.
96       TYPE_SERVICE_WORKERS,   // This is used for CookieTreeServiceWorkersNode.
97       TYPE_SERVICE_WORKER,    // This is used for CookieTreeServiceWorkerNode.
98       TYPE_SHARED_WORKERS,    // This is used for CookieTreeSharedWorkersNode.
99       TYPE_SHARED_WORKER,     // This is used for CookieTreeSharedWorkerNode.
100       TYPE_CACHE_STORAGES,    // This is used for CookieTreeCacheStoragesNode.
101       TYPE_CACHE_STORAGE,     // This is used for CookieTreeCacheStorageNode.
102       TYPE_MEDIA_LICENSES,    // This is used for CookieTreeMediaLicensesNode.
103       TYPE_MEDIA_LICENSE,     // This is used for CookieTreeMediaLicenseNode.
104     };
105 
106     DetailedInfo();
107     DetailedInfo(const DetailedInfo& other);
108     ~DetailedInfo();
109 
110     DetailedInfo& Init(NodeType type);
111     DetailedInfo& InitHost(const GURL& origin);
112     DetailedInfo& InitCookie(const net::CanonicalCookie* cookie);
113     DetailedInfo& InitDatabase(const content::StorageUsageInfo* usage_info);
114     DetailedInfo& InitLocalStorage(
115         const content::StorageUsageInfo* local_storage_info);
116     DetailedInfo& InitSessionStorage(
117         const content::StorageUsageInfo* session_storage_info);
118     DetailedInfo& InitAppCache(const content::StorageUsageInfo* usage_info);
119     DetailedInfo& InitIndexedDB(const content::StorageUsageInfo* usage_info);
120     DetailedInfo& InitFileSystem(
121         const browsing_data::FileSystemHelper::FileSystemInfo*
122             file_system_info);
123     DetailedInfo& InitQuota(
124         const BrowsingDataQuotaHelper::QuotaInfo* quota_info);
125     DetailedInfo& InitServiceWorker(
126         const content::StorageUsageInfo* usage_info);
127     DetailedInfo& InitSharedWorker(
128         const browsing_data::SharedWorkerHelper::SharedWorkerInfo*
129             shared_worker_info);
130     DetailedInfo& InitCacheStorage(const content::StorageUsageInfo* usage_info);
131     DetailedInfo& InitMediaLicense(
132         const BrowsingDataMediaLicenseHelper::MediaLicenseInfo*
133             media_license_info);
134 
135     NodeType node_type;
136     url::Origin origin;
137     const net::CanonicalCookie* cookie = nullptr;
138     // Used for AppCache, Database (WebSQL), IndexedDB, Service Worker, and
139     // Cache Storage node types.
140     const content::StorageUsageInfo* usage_info = nullptr;
141     const browsing_data::FileSystemHelper::FileSystemInfo* file_system_info =
142         nullptr;
143     const BrowsingDataQuotaHelper::QuotaInfo* quota_info = nullptr;
144     const browsing_data::SharedWorkerHelper::SharedWorkerInfo*
145         shared_worker_info = nullptr;
146     const BrowsingDataMediaLicenseHelper::MediaLicenseInfo* media_license_info =
147         nullptr;
148   };
149 
CookieTreeNode()150   CookieTreeNode() {}
CookieTreeNode(const base::string16 & title)151   explicit CookieTreeNode(const base::string16& title)
152       : ui::TreeNode<CookieTreeNode>(title) {}
~CookieTreeNode()153   ~CookieTreeNode() override {}
154 
155   // Recursively traverse the child nodes of this node and collect the storage
156   // size data.
157   virtual int64_t InclusiveSize() const;
158 
159   // Recursively traverse the child nodes and calculate the number of nodes of
160   // type CookieTreeCookieNode.
161   virtual int NumberOfCookies() const;
162 
163   // Delete backend storage for this node, and any children nodes. (E.g. delete
164   // the cookie from CookieMonster, clear the database, and so forth.)
165   virtual void DeleteStoredObjects();
166 
167   // Gets a pointer back to the associated model for the tree we are in.
168   virtual CookiesTreeModel* GetModel() const;
169 
170   // Returns a struct with detailed information used to populate the details
171   // part of the view.
172   virtual DetailedInfo GetDetailedInfo() const = 0;
173 
174  protected:
175   void AddChildSortedByTitle(std::unique_ptr<CookieTreeNode> new_child);
176 
177 #if !defined(OS_ANDROID)
178   // TODO (crbug.com/1113602): Remove this when all storage deletions from
179   // the browser process use the StoragePartition directly.
180   void ReportDeletionToAuditService(
181       const url::Origin& origin,
182       AccessContextAuditDatabase::StorageAPIType type);
183 #endif  // !defined(OS_ANDROID)
184 
185  private:
186   DISALLOW_COPY_AND_ASSIGN(CookieTreeNode);
187 };
188 
189 // CookieTreeRootNode ---------------------------------------------------------
190 // The node at the root of the CookieTree that gets inserted into the view.
191 class CookieTreeRootNode : public CookieTreeNode {
192  public:
193   explicit CookieTreeRootNode(CookiesTreeModel* model);
194   ~CookieTreeRootNode() override;
195 
196   CookieTreeHostNode* GetOrCreateHostNode(const GURL& url);
197 
198   // CookieTreeNode methods:
199   CookiesTreeModel* GetModel() const override;
200   DetailedInfo GetDetailedInfo() const override;
201 
202  private:
203   CookiesTreeModel* model_;
204 
205   DISALLOW_COPY_AND_ASSIGN(CookieTreeRootNode);
206 };
207 
208 // CookieTreeHostNode -------------------------------------------------------
209 class CookieTreeHostNode : public CookieTreeNode {
210  public:
211   // Returns the host node's title to use for a given URL.
212   static base::string16 TitleForUrl(const GURL& url);
213 
214   explicit CookieTreeHostNode(const GURL& url);
215   ~CookieTreeHostNode() override;
216 
217   // CookieTreeNode methods:
218   DetailedInfo GetDetailedInfo() const override;
219   int64_t InclusiveSize() const override;
220 
221   // CookieTreeHostNode methods:
222   CookieTreeCookiesNode* GetOrCreateCookiesNode();
223   CookieTreeDatabasesNode* GetOrCreateDatabasesNode();
224   CookieTreeLocalStoragesNode* GetOrCreateLocalStoragesNode();
225   CookieTreeSessionStoragesNode* GetOrCreateSessionStoragesNode();
226   CookieTreeAppCachesNode* GetOrCreateAppCachesNode();
227   CookieTreeIndexedDBsNode* GetOrCreateIndexedDBsNode();
228   CookieTreeFileSystemsNode* GetOrCreateFileSystemsNode();
229   CookieTreeServiceWorkersNode* GetOrCreateServiceWorkersNode();
230   CookieTreeSharedWorkersNode* GetOrCreateSharedWorkersNode();
231   CookieTreeCacheStoragesNode* GetOrCreateCacheStoragesNode();
232   CookieTreeQuotaNode* UpdateOrCreateQuotaNode(
233       std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info);
234   CookieTreeMediaLicensesNode* GetOrCreateMediaLicensesNode();
235 
canonicalized_host()236   std::string canonicalized_host() const { return canonicalized_host_; }
237 
238   // Creates an content exception for this origin of type
239   // ContentSettingsType::COOKIES.
240   void CreateContentException(content_settings::CookieSettings* cookie_settings,
241                               ContentSetting setting) const;
242 
243   // True if a content exception can be created for this origin.
244   bool CanCreateContentException() const;
245 
246   std::string GetHost() const;
247 
248   void UpdateHostUrl(const GURL& url);
249 
250  private:
251   // Pointers to the cookies, databases, local and session storage and appcache
252   // nodes.  When we build up the tree we need to quickly get a reference to
253   // the COOKIES node to add children. Checking each child and interrogating
254   // them to see if they are a COOKIES, APPCACHES, DATABASES etc node seems
255   // less preferable than storing an extra pointer per origin.
256   CookieTreeCookiesNode* cookies_child_ = nullptr;
257   CookieTreeDatabasesNode* databases_child_ = nullptr;
258   CookieTreeLocalStoragesNode* local_storages_child_ = nullptr;
259   CookieTreeSessionStoragesNode* session_storages_child_ = nullptr;
260   CookieTreeAppCachesNode* appcaches_child_ = nullptr;
261   CookieTreeIndexedDBsNode* indexed_dbs_child_ = nullptr;
262   CookieTreeFileSystemsNode* file_systems_child_ = nullptr;
263   CookieTreeQuotaNode* quota_child_ = nullptr;
264   CookieTreeServiceWorkersNode* service_workers_child_ = nullptr;
265   CookieTreeSharedWorkersNode* shared_workers_child_ = nullptr;
266   CookieTreeCacheStoragesNode* cache_storages_child_ = nullptr;
267   CookieTreeMediaLicensesNode* media_licenses_child_ = nullptr;
268 
269   // The URL for which this node was initially created.
270   GURL url_;
271 
272   std::string canonicalized_host_;
273 
274   DISALLOW_COPY_AND_ASSIGN(CookieTreeHostNode);
275 };
276 
277 // CookiesTreeModel -----------------------------------------------------------
278 class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> {
279  public:
280   CookiesTreeModel(std::unique_ptr<LocalDataContainer> data_container,
281                    ExtensionSpecialStoragePolicy* special_storage_policy);
282   // As above, but also provides the tree model with a pointer to the Access
283   // Context Audit service. This allows the tree model to report deletion events
284   // to the service. This must be used whenever the service exists to ensure
285   // audit record consistency.
286   // TODO (crbug.com/1113602): Remove this constructor when all deletions are
287   // performed directly against the StoragePartition and the tree model doesn't
288   // require knowledge of the audit service.
289   CookiesTreeModel(std::unique_ptr<LocalDataContainer> data_container,
290                    ExtensionSpecialStoragePolicy* special_storage_policy,
291                    AccessContextAuditService* access_context_audit_service);
292   ~CookiesTreeModel() override;
293 
294   // Given a CanonicalCookie, return the ID of the message which should be
295   // displayed in various ports' "Send for:" UI.
296   static int GetSendForMessageID(const net::CanonicalCookie& cookie);
297 
298   // Because non-cookie nodes are fetched in a background thread, they are not
299   // present at the time the Model is created. The Model then notifies its
300   // observers for every item added from databases, local storage, and
301   // appcache. We extend the Observer interface to add notifications before and
302   // after these batch inserts.
303   class Observer : public ui::TreeModelObserver {
304    public:
TreeModelBeginBatch(CookiesTreeModel * model)305     virtual void TreeModelBeginBatch(CookiesTreeModel* model) {}
TreeModelEndBatch(CookiesTreeModel * model)306     virtual void TreeModelEndBatch(CookiesTreeModel* model) {}
307   };
308 
309   // This class defines the scope for batch updates. It can be created as a
310   // local variable and the destructor will terminate the batch update, if one
311   // has been started.
312   class ScopedBatchUpdateNotifier {
313    public:
314     ScopedBatchUpdateNotifier(CookiesTreeModel* model,
315                               CookieTreeNode* node);
316     ~ScopedBatchUpdateNotifier();
317 
318     void StartBatchUpdate();
319 
320    private:
321     CookiesTreeModel* model_;
322     CookieTreeNode* node_;
323     bool batch_in_progress_ = false;
324   };
325 
326   // ui::TreeModel methods:
327   // Returns the set of icons for the nodes in the tree. You only need override
328   // this if you don't want to use the default folder icons.
329   void GetIcons(std::vector<gfx::ImageSkia>* icons) override;
330 
331   // Returns the index of the icon to use for |node|. Return -1 to use the
332   // default icon. The index is relative to the list of icons returned from
333   // GetIcons.
334   int GetIconIndex(ui::TreeModelNode* node) override;
335 
336   // CookiesTreeModel methods:
337   void DeleteAllStoredObjects();
338 
339   // Deletes a specific node in the tree, identified by |cookie_node|, and its
340   // subtree.
341   void DeleteCookieNode(CookieTreeNode* cookie_node);
342 
343   // Filter the origins to only display matched results.
344   void UpdateSearchResults(const base::string16& filter);
345 
346 #if BUILDFLAG(ENABLE_EXTENSIONS)
347   // Returns the set of extensions which protect the data item represented by
348   // this node from deletion.
349   // Returns nullptr if the node doesn't represent a protected data item or the
350   // special storage policy is nullptr.
351   const extensions::ExtensionSet* ExtensionsProtectingNode(
352       const CookieTreeNode& cookie_node);
353 #endif
354 
355   // Manages CookiesTreeModel::Observers. This will also call
356   // TreeNodeModel::AddObserver so that it gets all the proper notifications.
357   // Note that the converse is not true: simply adding a TreeModelObserver will
358   // not get CookiesTreeModel::Observer notifications.
359   virtual void AddCookiesTreeObserver(Observer* observer);
360   virtual void RemoveCookiesTreeObserver(Observer* observer);
361 
362   // Methods that update the model based on the data retrieved by the browsing
363   // data helpers.
364   void PopulateAppCacheInfo(LocalDataContainer* container);
365   void PopulateCookieInfo(LocalDataContainer* container);
366   void PopulateDatabaseInfo(LocalDataContainer* container);
367   void PopulateLocalStorageInfo(LocalDataContainer* container);
368   void PopulateSessionStorageInfo(LocalDataContainer* container);
369   void PopulateIndexedDBInfo(LocalDataContainer* container);
370   void PopulateFileSystemInfo(LocalDataContainer* container);
371   void PopulateQuotaInfo(LocalDataContainer* container);
372   void PopulateServiceWorkerUsageInfo(LocalDataContainer* container);
373   void PopulateSharedWorkerInfo(LocalDataContainer* container);
374   void PopulateCacheStorageUsageInfo(LocalDataContainer* container);
375   void PopulateMediaLicenseInfo(LocalDataContainer* container);
376 
377   // Returns the Access Context Audit service provided to the cookies tree model
378   // as part of the constructor, or nullptr if no service was provided.
access_context_audit_service()379   AccessContextAuditService* access_context_audit_service() {
380     return access_context_audit_service_;
381   }
382 
data_container()383   LocalDataContainer* data_container() {
384     return data_container_.get();
385   }
386 
387   // Set the number of |batches_expected| this class should expect to receive.
388   // If |reset| is true, then this is a new set of batches, but if false, then
389   // this is a revised number (batches originally counted should no longer be
390   // expected).
391   void SetBatchExpectation(int batches_expected, bool reset);
392 
393   // Create CookiesTreeModel by profile info.
394   static std::unique_ptr<CookiesTreeModel> CreateForProfile(Profile* profile);
395 
396   static browsing_data::CookieHelper::IsDeletionDisabledCallback
397   GetCookieDeletionDisabledCallback(Profile* profile);
398 
399  private:
400   enum CookieIconIndex { COOKIE = 0, DATABASE = 1 };
401 
402   // Record that one batch has been delivered.
403   void RecordBatchSeen();
404 
405   // Record that one batch has begun processing. If this is the first batch then
406   // observers will be notified that batch processing has started.
407   void NotifyObserverBeginBatch();
408 
409   // Record that one batch has finished processing. If this is the last batch
410   // then observers will be notified that batch processing has ended.
411   void NotifyObserverEndBatch();
412 
413   // Notifies observers if expected batch count has been delievered and all
414   // batches have finished processing.
415   void MaybeNotifyBatchesEnded();
416 
417   void PopulateAppCacheInfoWithFilter(LocalDataContainer* container,
418                                       ScopedBatchUpdateNotifier* notifier,
419                                       const base::string16& filter);
420   void PopulateCookieInfoWithFilter(LocalDataContainer* container,
421                                     ScopedBatchUpdateNotifier* notifier,
422                                     const base::string16& filter);
423   void PopulateDatabaseInfoWithFilter(LocalDataContainer* container,
424                                       ScopedBatchUpdateNotifier* notifier,
425                                       const base::string16& filter);
426   void PopulateLocalStorageInfoWithFilter(LocalDataContainer* container,
427                                           ScopedBatchUpdateNotifier* notifier,
428                                           const base::string16& filter);
429   void PopulateSessionStorageInfoWithFilter(LocalDataContainer* container,
430                                             ScopedBatchUpdateNotifier* notifier,
431                                             const base::string16& filter);
432   void PopulateIndexedDBInfoWithFilter(LocalDataContainer* container,
433                                        ScopedBatchUpdateNotifier* notifier,
434                                        const base::string16& filter);
435   void PopulateFileSystemInfoWithFilter(LocalDataContainer* container,
436                                         ScopedBatchUpdateNotifier* notifier,
437                                         const base::string16& filter);
438   void PopulateQuotaInfoWithFilter(LocalDataContainer* container,
439                                    ScopedBatchUpdateNotifier* notifier,
440                                    const base::string16& filter);
441   void PopulateServiceWorkerUsageInfoWithFilter(
442       LocalDataContainer* container,
443       ScopedBatchUpdateNotifier* notifier,
444       const base::string16& filter);
445   void PopulateSharedWorkerInfoWithFilter(LocalDataContainer* container,
446                                           ScopedBatchUpdateNotifier* notifier,
447                                           const base::string16& filter);
448   void PopulateCacheStorageUsageInfoWithFilter(
449       LocalDataContainer* container,
450       ScopedBatchUpdateNotifier* notifier,
451       const base::string16& filter);
452   void PopulateMediaLicenseInfoWithFilter(LocalDataContainer* container,
453                                           ScopedBatchUpdateNotifier* notifier,
454                                           const base::string16& filter);
455 
456 #if BUILDFLAG(ENABLE_EXTENSIONS)
457   // The extension special storage policy; see ExtensionsProtectingNode() above.
458   scoped_refptr<ExtensionSpecialStoragePolicy> special_storage_policy_;
459 #endif
460 
461   // Map of app ids to LocalDataContainer objects to use when retrieving
462   // locally stored data.
463   std::unique_ptr<LocalDataContainer> data_container_;
464 
465   // The CookiesTreeModel maintains a separate list of observers that are
466   // specifically of the type CookiesTreeModel::Observer.
467   base::ObserverList<Observer>::Unchecked cookies_observer_list_;
468 
469   AccessContextAuditService* access_context_audit_service_ = nullptr;
470 
471   // Keeps track of how many batches the consumer of this class says it is going
472   // to send.
473   int batches_expected_ = 0;
474 
475   // Keeps track of how many batches we've seen.
476   int batches_seen_ = 0;
477 
478   // Counts how many batches have started already. If this is non-zero and lower
479   // than batches_ended_, then this model is still batching updates.
480   int batches_started_ = 0;
481 
482   // Counts how many batches have finished.
483   int batches_ended_ = 0;
484 };
485 
486 #endif  // CHROME_BROWSER_BROWSING_DATA_COOKIES_TREE_MODEL_H_
487