[go: nahoru, domu]

blob: b520e8a8e8bbdba19fa4591d5f8c0ae6c655cf05 [file] [log] [blame]
// 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 CONTENT_BROWSER_FIRST_PARTY_SETS_DATABASE_FIRST_PARTY_SETS_DATABASE_H_
#define CONTENT_BROWSER_FIRST_PARTY_SETS_DATABASE_FIRST_PARTY_SETS_DATABASE_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "content/common/content_export.h"
#include "sql/meta_table.h"
namespace net {
class FirstPartySetEntry;
class FirstPartySetsCacheFilter;
class FirstPartySetsContextConfig;
class GlobalFirstPartySets;
class SchemefulSite;
} // namespace net
namespace sql {
class Database;
class Statement;
} // namespace sql
namespace content {
// Wraps its own `sql::Database` instance on behalf of the First-Party Sets
// database implementation. This class must be accessed and destroyed on the
// same sequence. The sequence must outlive |this|.
//
// Note that the current implementation relies on DB being accessed by a
// singleton only and is already sequence-safe.
class CONTENT_EXPORT FirstPartySetsDatabase {
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class InitStatus {
// `LazyInit()` has not yet been called.
kUnattempted = 0,
// `LazyInit()` was successful.
kSuccess = 1,
// `LazyInit()` failed and a more specific error wasn't diagnosed.
kError = 2,
// `LazyInit()` failed due to a compatible version number being too high.
kTooNew = 3,
// `LazyInit()` failed due to a version number being too low.
kTooOld = 4,
// `LazyInit()` was successful but data is considered corrupted.
kCorrupted = 5,
kMaxValue = kCorrupted,
};
explicit FirstPartySetsDatabase(base::FilePath db_path);
FirstPartySetsDatabase(const FirstPartySetsDatabase&) = delete;
FirstPartySetsDatabase& operator=(const FirstPartySetsDatabase&) = delete;
FirstPartySetsDatabase(const FirstPartySetsDatabase&&) = delete;
FirstPartySetsDatabase& operator=(const FirstPartySetsDatabase&&) = delete;
~FirstPartySetsDatabase();
// Stores the overall First-Party Sets for the given `browser_context_id` into
// database in one transaction.
[[nodiscard]] bool PersistSets(
const std::string& browser_context_id,
const net::GlobalFirstPartySets& sets,
const net::FirstPartySetsContextConfig& config);
// Stores the `sites` to be cleared for the `browser_context_id` into
// database, and returns true on success.
[[nodiscard]] bool InsertSitesToClear(
const std::string& browser_context_id,
const base::flat_set<net::SchemefulSite>& sites);
// Stores the `browser_context_id` that has performed clearing into
// browser_contexts_cleared table, and returns true on success.
[[nodiscard]] bool InsertBrowserContextCleared(
const std::string& browser_context_id);
// TODO(crbug.com/1219656): Consider returning absl::nullopt for all the
// fetching methods when having query errors
// Gets the global First-Party Sets used by `browser_context_id`.
[[nodiscard]] net::GlobalFirstPartySets GetGlobalSets(
const std::string& browser_context_id);
// Gets the sites to clear filters. The first filter holds the list of sites
// that haven't had their cookies/storage cleared, the second filter is the
// cache filter that holds the current `run_count_` and a map of sites to
// their `marked_at_run`, containing all the sites that were added into DB to
// be cleared in a certain browser run, for the `browser_context_id`.
[[nodiscard]] std::pair<std::vector<net::SchemefulSite>,
net::FirstPartySetsCacheFilter>
GetSitesToClearFilters(const std::string& browser_context_id);
// Gets the previously-stored policy configurations for the
// `browser_context_id`.
[[nodiscard]] net::FirstPartySetsContextConfig FetchPolicyConfigurations(
const std::string& browser_context_id);
// Check whether the `browser_context_id` has performed clearing.
[[nodiscard]] bool HasEntryInBrowserContextsClearedForTesting(
const std::string& browser_context_id);
private:
// Stores the public First-Party Sets into database, and keeps track of the
// the sets version used by `browser_context_id`. `sets_version` must be
// valid. Returns true on success.
[[nodiscard]] bool SetPublicSets(const std::string& browser_context_id,
const net::GlobalFirstPartySets& sets);
// Stores the Manual Sets into manual_sets table, and returns true on success.
// Inserting new manual sets will wipe out pre-existing manual sets for the
// given 'browser_context_id'
[[nodiscard]] bool InsertManualSets(
const std::string& browser_context_id,
const base::flat_map<net::SchemefulSite, net::FirstPartySetEntry>&
manual_sets);
// Stores the policy configurations into policy_configurations table, and
// returns true on success. Note that inserting new configurations will
// wipe out the pre-existing ones for the given `browser_context_id`.
[[nodiscard]] bool InsertPolicyConfigurations(
const std::string& browser_context_id,
const net::FirstPartySetsContextConfig& config);
// Gets the previously-stored manual_sets for the `browser_context_id`.
[[nodiscard]] base::flat_map<net::SchemefulSite, net::FirstPartySetEntry>
FetchManualSets(const std::string& browser_context_id);
// Gets the list of sites to clear for the `browser_context_id`.
[[nodiscard]] std::vector<net::SchemefulSite> FetchSitesToClear(
const std::string& browser_context_id);
// Gets all the sites and mapped to the value of `run_count_`, which
// represents the site was added into DB to be cleared in a certain browser
// run, for the `browser_context_id`.
[[nodiscard]] base::flat_map<net::SchemefulSite, int64_t>
FetchAllSitesToClearFilter(const std::string& browser_context_id);
// Called at the start of each public operation, and initializes the database
// if it isn't already initialized.
[[nodiscard]] bool LazyInit() VALID_CONTEXT_REQUIRED(sequence_checker_);
// Opens a persistent database with the absolute path `db_path_`, creating the
// file if it does not yet exist. Returns whether opening was successful.
[[nodiscard]] bool OpenDatabase() VALID_CONTEXT_REQUIRED(sequence_checker_);
// Callback for database errors.
void DatabaseErrorCallback(int extended_error, sql::Statement* stmt)
VALID_CONTEXT_REQUIRED(sequence_checker_);
// Helper function to implement internals of `LazyInit()`.
[[nodiscard]] InitStatus InitializeTables()
VALID_CONTEXT_REQUIRED(sequence_checker_);
// Upgrades `db_` to the latest schema, and updates the version stored in
// `meta_table_` accordingly. Returns false on failure.
[[nodiscard]] bool UpgradeSchema() VALID_CONTEXT_REQUIRED(sequence_checker_);
[[nodiscard]] bool MigrateToVersion3()
VALID_CONTEXT_REQUIRED(sequence_checker_);
// Increase the `run_count` stored in the meta table by 1. Should only be
// called once during DB initialization. The value of `run_count` should
// never be negative.
void IncreaseRunCount() VALID_CONTEXT_REQUIRED(sequence_checker_);
// Deletes the database and returns whether the operation was successful.
//
// It is OK to call `Destroy()` regardless of whether db init was successful.
[[nodiscard]] bool Destroy() VALID_CONTEXT_REQUIRED(sequence_checker_);
// The path to the database.
base::FilePath db_path_ GUARDED_BY_CONTEXT(sequence_checker_);
// The database containing the actual data. May be null if the database:
// - could not be opened
// - table/index initialization failed
std::unique_ptr<sql::Database> db_ GUARDED_BY_CONTEXT(sequence_checker_);
// Stores the version information and `run_count`.
sql::MetaTable meta_table_ GUARDED_BY_CONTEXT(sequence_checker_);
// Initialization status of `db_`.
InitStatus db_status_ GUARDED_BY_CONTEXT(sequence_checker_){
InitStatus::kUnattempted};
// Contains the count of the current browser run after database is initialized
// successfully, which should be a positive number and should only be set
// once.
int64_t run_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace content
#endif // CONTENT_BROWSER_FIRST_PARTY_SETS_DATABASE_FIRST_PARTY_SETS_DATABASE_H_