File: browsing_data_model.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (366 lines) | stat: -rw-r--r-- 15,811 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_BROWSING_DATA_CONTENT_BROWSING_DATA_MODEL_H_
#define COMPONENTS_BROWSING_DATA_CONTENT_BROWSING_DATA_MODEL_H_

#include <iterator>
#include <map>
#include <variant>

#include "base/containers/enum_set.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "components/browsing_data/content/browsing_data_quota_helper.h"
#include "components/browsing_data/content/shared_worker_info.h"
#include "components/webid/federated_identity_data_model.h"
#include "content/public/browser/attribution_data_model.h"
#include "content/public/browser/cdm_storage_data_model.h"
#include "content/public/browser/interest_group_manager.h"
#include "content/public/browser/private_aggregation_data_model.h"
#include "content/public/browser/session_storage_usage_info.h"
#include "net/cookies/canonical_cookie.h"
#include "net/shared_dictionary/shared_dictionary_isolation_key.h"
#include "services/network/public/mojom/device_bound_sessions.mojom.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
#include "url/origin.h"

namespace content {
class BrowserContext;
class StoragePartition;
}

// Provides a model interface into a collection of Browsing Data for use in the
// UI. Exposes a uniform view into browsing data based on the concept of
// "data owners", which denote which entity the data should be closely
// associated with in UI surfaces.
class BrowsingDataModel {
 public:
  // The entity that logically owns a set of data. All browsing data will be
  // grouped by its owner.
  using DataOwner = std::variant<std::string,  // Hostname
                                 url::Origin>;

  // Storage types which are represented by the model. Some types have
  // incomplete implementations, and are marked as such.
  // TODO(crbug.com/40205603): Complete implementations for all browsing data.
  enum class StorageType {
    kTrustTokens = 1,  // Only issuance information considered.
    kSharedStorage = 2,
    kLocalStorage,
    kSessionStorage,
    kInterestGroup,
    kAttributionReporting,
    kPrivateAggregation,
    kQuotaStorage,
    kSharedDictionary,
    kSharedWorker,
    kCookie,
    kCdmStorage,
    kDeviceBoundSession,

    kFirstType = kTrustTokens,
    kLastType = kDeviceBoundSession,
    kExtendedDelegateRange =
        63,  // This is needed to include delegate values when adding delegate
             // browsing data to the model.
  };
  using StorageTypeSet = base::EnumSet<StorageType,
                                       StorageType::kFirstType,
                                       StorageType::kExtendedDelegateRange>;

  // The information which uniquely identifies this browsing data. The set of
  // data an entry represents can be pulled from the relevant storage backends
  // using this information.
  typedef std::variant<url::Origin,        // Single origin, e.g. Trust Tokens
                       blink::StorageKey,  // Partitioned JS storage
                       content::InterestGroupManager::InterestGroupDataKey,
                       content::AttributionDataModel::DataKey,
                       content::PrivateAggregationDataModel::DataKey,
                       content::SessionStorageUsageInfo,
                       net::SharedDictionaryIsolationKey,
                       browsing_data::SharedWorkerInfo,
                       net::CanonicalCookie,
                       webid::FederatedIdentityDataModel::DataKey,
                       net::device_bound_sessions::SessionKey
                       // TODO(crbug.com/40205603): Additional backend keys.
                       >
      DataKey;

  // Information about the data pointed at by a DataKey.
  struct DataDetails {
    ~DataDetails();
    bool operator==(const DataDetails& other) const;

    // An EnumSet of storage types for this data.
    StorageTypeSet storage_types;

    // The on-disk size of this storage.
    uint64_t storage_size = 0;

    // The number of cookies included in this storage. This is only included to
    // support legacy UI surfaces.
    // TODO(crbug.com/40862729): Remove this when UI no longer requires it.
    uint64_t cookie_count = 0;

    // Flag indicating if the data was blocked in a third-party context.
    bool blocked_third_party = false;
  };

  // A view of a single "unit" of browsing data. Considered a "view" as it holds
  // references to data contained within the model.
  struct BrowsingDataEntryView {
    ~BrowsingDataEntryView();
    BrowsingDataEntryView(const BrowsingDataEntryView& other) = delete;

    // Returns true if |origin| is within this browsing data's  owning entity.
    bool Matches(const url::Origin& origin) const;

    // Returns the non-1P SchemefulSite this data is partitioned on. Returns
    // base::nullopt if the data is not partitioned, or is the 1P partition.
    std::optional<net::SchemefulSite> GetThirdPartyPartitioningSite() const;

    // The logical owner of this browsing data. This is the entity which this
    // information will be most strongly associated with in UX surfaces.
    const raw_ref<const DataOwner, DanglingUntriaged> data_owner;

    // The unique identifier for the data represented by this entry.
    const raw_ref<const DataKey, DanglingUntriaged> data_key;

    // Information about the data represented by this entry.
    const raw_ref<const DataDetails, DanglingUntriaged> data_details;

   private:
    friend class BrowsingDataModel;

    BrowsingDataEntryView(const DataOwner& data_owner,
                          const DataKey& data_key,
                          const DataDetails& data_details);
  };

  // A delegate to handle non components/ data type retrieval and deletion.
  class Delegate {
   public:
    struct DelegateEntry {
      DelegateEntry(const DataKey& data_key,
                    StorageType storage_type,
                    uint64_t storage_size);
      DelegateEntry(const DelegateEntry& other);
      ~DelegateEntry();
      DataKey data_key;
      StorageType storage_type;
      uint64_t storage_size;
    };

    // Retrieves all possible data keys with its associated storage size.
    virtual void GetAllDataKeys(
        base::OnceCallback<void(std::vector<DelegateEntry>)> callback) = 0;

    // Removes all data that matches the data key.
    virtual void RemoveDataKey(const DataKey& data_key,
                               StorageTypeSet storage_types,
                               base::OnceClosure callback) = 0;

    // Returns the owner of the data identified by the given DataKey and
    // StorageType, or nullopt if the delegate does not manage the entity that
    // owns the given data.
    virtual std::optional<DataOwner> GetDataOwner(
        const DataKey& data_key,
        StorageType storage_type) const = 0;

    // Returns true if storage type is Cookie-like i.e. non kAPI type.
    virtual std::optional<bool> IsStorageTypeCookieLike(
        StorageType storage_type) const = 0;

    // Returns whether the delegate considers `storage_type` to be blocked by
    // third party cookie blocking, utilizing `data_key` to exclude partitioned
    // data. Returns nullopt if the delegate does not manage the storage type.
    // This method isn't aware of the context in which the data key is being
    // accessed and may return false positive in case it was called for a first
    // party key in a first party context.
    virtual std::optional<bool> IsBlockedByThirdPartyCookieBlocking(
        const DataKey& data_key,
        StorageType storage_type) const = 0;

    // Returns whether cookie deletion for a given `url` is disabled.
    virtual bool IsCookieDeletionDisabled(const GURL& url) = 0;

    // Get a WeakPtr to the instance.
    virtual base::WeakPtr<Delegate> AsWeakPtr() = 0;

    virtual ~Delegate() = default;
  };

  // The model provides a single interface for retrieving browsing data, in the
  // form of an Input iterator (read-only, increment only, no random access)
  // over BrowsingDataEntryViews.
  // Iterators are invalidated whenever the model is updated.
  using DataKeyEntries = std::map<DataKey, DataDetails>;
  using BrowsingDataEntries = std::map<DataOwner, DataKeyEntries>;
  struct Iterator {
    ~Iterator();
    Iterator(const Iterator& iterator);
    bool operator==(const Iterator& other) const;

    // Input iterator functionality. These declarations allow STL functions to
    // make use of the iterator interface.
    // More details: https://en.cppreference.com/w/cpp/iterator/iterator_tags
    using iterator_category = std::input_iterator_tag;
    using difference_type = std::ptrdiff_t;
    using value_type = BrowsingDataEntryView;
    using pointer = BrowsingDataEntryView*;
    using reference = BrowsingDataEntryView&;
    BrowsingDataEntryView operator*() const;
    Iterator& operator++();

   private:
    friend class BrowsingDataModel;

    Iterator(BrowsingDataEntries::const_iterator outer_iterator,
             BrowsingDataEntries::const_iterator end_outer_iterator);

    BrowsingDataEntries::const_iterator outer_iterator_;
    DataKeyEntries::const_iterator inner_iterator_;
    const BrowsingDataEntries::const_iterator outer_end_iterator_;
  };

  Iterator begin() const;
  Iterator end() const;

  virtual ~BrowsingDataModel();

  // Returns number of entries within the Model.
  size_t size() const { return browsing_data_entries_.size(); }

  // Retrieves the host from the data owner.
  static const std::string GetHost(const DataOwner& data_owner);

  // Retrieves the owning origin for a specific data key.
  static const url::Origin GetOriginForDataKey(
      const BrowsingDataModel::DataKey& data_key);

  // Consults supported storage backends to create and populate a Model based
  // on the current state of `browser_context`.
  static void BuildFromDisk(
      content::BrowserContext* browser_context,
      std::unique_ptr<Delegate> delegate,
      base::OnceCallback<void(std::unique_ptr<BrowsingDataModel>)>
          complete_callback);

  // Consults supported storage backends to create and populate a Model based
  // on the current state of `storage_partition`.
  static void BuildFromNonDefaultStoragePartition(
      content::StoragePartition* storage_partition,
      std::unique_ptr<Delegate> delegate,
      base::OnceCallback<void(std::unique_ptr<BrowsingDataModel>)>
          complete_callback);

  // Creates and returns an empty model, for population via AddBrowsingData().
  static std::unique_ptr<BrowsingDataModel> BuildEmpty(
      content::StoragePartition* storage_partition,
      std::unique_ptr<Delegate> delegate);

  // Directly add browsing data to the Model. The appropriate BrowsingDataEntry
  // will be created or modified. Typically this should only be used when the
  // model was created using BuildEmpty().
  void AddBrowsingData(const DataKey& data_key,
                       StorageType storage_type,
                       uint64_t storage_size,
                       // TODO(crbug.com/40862729): Deprecate cookie count.
                       uint64_t cookie_count = 0,
                       bool blocked_third_party = false);

  // Removes all browsing data associated with `data_owner`, reaches out to
  // all supported storage backends to remove the data, and updates the model.
  // The in-memory representation of the model is updated immediately, while
  // actual deletion from disk occurs async, completion reported by `completed`.
  // Invalidates any iterators.
  // Virtual to allow an in-memory only fake to be created.
  virtual void RemoveBrowsingData(const DataOwner& data_owner,
                                  base::OnceClosure completed);

  // Removes data for `data_owner` partitioned on `top_level_site`.
  // This supports more granular data deletion needed by UI surfaces.
  // The in-memory representation of the model is updated immediately, while
  // actual deletion from disk occurs async, completion reported by `completed`.
  // Invalidates any iterators.
  // Virtual to allow an in-memory only fake to be created.
  virtual void RemovePartitionedBrowsingData(
      const DataOwner& data_owner,
      const net::SchemefulSite& top_level_site,
      base::OnceClosure completed);

  // Removes data for `data_owner` which is not partitioned, or is the 1P
  // partition. This supports more granular data deletion needed by UI surfaces.
  // Virtual to allow an in-memory only fake to be created.
  virtual void RemoveUnpartitionedBrowsingData(const DataOwner& data_owner,
                                               base::OnceClosure completed);

  // Returns true if storage type is Cookie-like i.e. non kAPI type.
  // This can't be static as it requires to consult the delegate.
  bool IsStorageTypeCookieLike(StorageType storage_type) const;

  // Returns whether the provided `storage_type` is blocked when third party
  // cookies are blocked, utilizing `data_key` to exclude partitioned data.
  // This method isn't aware of the context in which the data key is being
  // accessed and may return false positive in case it was called for a first
  // party key in a first party context.
  bool IsBlockedByThirdPartyCookieBlocking(const DataKey& data_key,
                                           StorageType storage_type) const;

 protected:
  friend class BrowsingDataModelTest;

  static void BuildFromStoragePartition(
      content::StoragePartition* storage_partition,
      std::unique_ptr<Delegate> delegate,
      base::OnceCallback<void(std::unique_ptr<BrowsingDataModel>)>
          complete_callback);

  // Takes a list of `browsing_data_entries` to remove from disk and runs
  // `completed` callback on completion.
  virtual void RemoveBrowsingDataEntriesFromDisk(
      const BrowsingDataModel::DataKeyEntries& browsing_data_entries,
      base::OnceClosure completed);

  // Private as one of the static BuildX functions should be used instead.
  explicit BrowsingDataModel(
      content::StoragePartition* storage_partition,
      std::unique_ptr<Delegate> delegate
      // TODO(crbug.com/40205603): Inject other dependencies.
  );

  void GetAffectedDataKeyEntriesForRemovePartitionedBrowsingData(
      const DataOwner& data_owner,
      const net::SchemefulSite& top_level_site,
      DataKeyEntries& affected_data_key_entries);

  // Pulls information from disk and populate the model.
  // Virtual to allow an in-memory only fake to be created.
  virtual void PopulateFromDisk(base::OnceClosure finished_callback);

  // Backing data structure for this model. Is a map from data owners to a
  // list of tuples (stored as a map) of <DataKey, DataDetails>. Building the
  // model requires updating existing entries as data becomes available, so
  // fast lookup is required. Similarly, keying the outer map on data owner
  // supports removal by data owner performantly.
  BrowsingDataEntries browsing_data_entries_;

  // Non-owning pointers to storage backends. All derivable from a browser
  // context, but broken out to allow easier injection in tests.
  // TODO(crbug.com/40205603): More backends to come, they should all be broken
  // out from the browser context at the appropriate level.
  raw_ptr<content::StoragePartition, DanglingUntriaged> storage_partition_;

  // Used to handle quota managed data on IO thread.
  scoped_refptr<BrowsingDataQuotaHelper> quota_helper_;

  // Owning pointer to the delegate responsible for non components/ data
  // retrieval and removal.
  std::unique_ptr<Delegate> delegate_;
};

#endif  // COMPONENTS_BROWSING_DATA_CONTENT_BROWSING_DATA_MODEL_H_