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_
|