chromium/content/browser/attribution_reporting/attribution_storage_sql.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/attribution_reporting/attribution_storage_sql.h"

#include <stddef.h>
#include <stdint.h>

#include <functional>
#include <iterator>
#include <limits>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/containers/enum_set.h"
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/overloaded.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/numerics/checked_math.h"
#include "base/ranges/algorithm.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "base/uuid.h"
#include "components/attribution_reporting/aggregatable_dedup_key.h"
#include "components/attribution_reporting/aggregatable_trigger_config.h"
#include "components/attribution_reporting/aggregatable_trigger_data.h"
#include "components/attribution_reporting/aggregatable_utils.h"
#include "components/attribution_reporting/aggregatable_values.h"
#include "components/attribution_reporting/aggregation_keys.h"
#include "components/attribution_reporting/attribution_scopes_data.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/destination_set.h"
#include "components/attribution_reporting/event_report_windows.h"
#include "components/attribution_reporting/event_trigger_data.h"
#include "components/attribution_reporting/features.h"
#include "components/attribution_reporting/filters.h"
#include "components/attribution_reporting/privacy_math.h"
#include "components/attribution_reporting/source_registration.h"
#include "components/attribution_reporting/source_registration_time_config.mojom-forward.h"
#include "components/attribution_reporting/source_type.mojom.h"
#include "components/attribution_reporting/suitable_origin.h"
#include "components/attribution_reporting/trigger_config.h"
#include "components/attribution_reporting/trigger_data_matching.mojom.h"
#include "components/attribution_reporting/trigger_registration.h"
#include "content/browser/attribution_reporting/aggregatable_attribution_utils.h"
#include "content/browser/attribution_reporting/aggregatable_debug_rate_limit_table.h"
#include "content/browser/attribution_reporting/aggregatable_debug_report.h"
#include "content/browser/attribution_reporting/attribution_features.h"
#include "content/browser/attribution_reporting/attribution_info.h"
#include "content/browser/attribution_reporting/attribution_report.h"
#include "content/browser/attribution_reporting/attribution_reporting.pb.h"
#include "content/browser/attribution_reporting/attribution_resolver_delegate.h"
#include "content/browser/attribution_reporting/attribution_storage_sql_migrations.h"
#include "content/browser/attribution_reporting/attribution_trigger.h"
#include "content/browser/attribution_reporting/common_source_info.h"
#include "content/browser/attribution_reporting/create_report_result.h"
#include "content/browser/attribution_reporting/rate_limit_result.h"
#include "content/browser/attribution_reporting/sql_queries.h"
#include "content/browser/attribution_reporting/sql_utils.h"
#include "content/browser/attribution_reporting/storable_source.h"
#include "content/browser/attribution_reporting/store_source_result.h"
#include "content/browser/attribution_reporting/stored_source.h"
#include "content/public/browser/attribution_data_model.h"
#include "net/base/schemeful_site.h"
#include "services/network/public/cpp/features.h"
#include "sql/database.h"
#include "sql/error_delegate_util.h"
#include "sql/meta_table.h"
#include "sql/recovery.h"
#include "sql/statement.h"
#include "sql/statement_id.h"
#include "sql/transaction.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/aggregation_service/aggregatable_report.mojom.h"
#include "url/origin.h"

namespace content {

namespace {

AggregatableResult;
EventLevelResult;

AggregatableTriggerConfig;
AttributionScopesData;
EventReportWindows;
SuitableOrigin;
SourceType;
TriggerDataMatching;

const base::FilePath::CharType kDatabasePath[] =);

constexpr int64_t kUnsetRecordId =;

void RecordInitializationStatus(
    const AttributionStorageSql::InitStatus status) {}

void RecordSourcesDeleted(int count) {}

void RecordReportsDeleted(int event_count, int aggregatable_count) {}

int64_t SerializeUint64(uint64_t data) {}

uint64_t DeserializeUint64(int64_t data) {}

// Prevent these functions from being called in the wrong direction.
int64_t SerializeUint64(int64_t data) = delete;
uint64_t DeserializeUint64(uint64_t data) = delete;

int SerializeAttributionLogic(StoredSource::AttributionLogic val) {}

std::optional<StoredSource::AttributionLogic> DeserializeAttributionLogic(
    int val) {}

int SerializeSourceType(SourceType val) {}

int SerializeReportType(AttributionReport::Type val) {}

std::optional<AttributionReport::Type> DeserializeReportType(int val) {}

std::optional<StoredSource::ActiveState> GetSourceActiveState(
    bool event_level_active,
    bool aggregatable_active) {}

void BindUint64OrNull(sql::Statement& statement,
                      int col,
                      std::optional<uint64_t> value) {}

std::optional<uint64_t> ColumnUint64OrNull(sql::Statement& statement, int col) {}

constexpr int kSourceColumnCount =;

int64_t GetStorageFileSizeKB(const base::FilePath& path_to_database) {}

}  // namespace

struct AttributionStorageSql::ReportCorruptionStatusSetAndIds {};

// Helper to deserialize source rows. See `GetActiveSources()` for the
// expected ordering of columns used for the input to this function.
base::expected<AttributionStorageSql::StoredSourceData,
               AttributionStorageSql::ReportCorruptionStatusSetAndIds>
AttributionStorageSql::ReadSourceFromStatement(sql::Statement& statement) {}

std::optional<AttributionStorageSql::StoredSourceData>
AttributionStorageSql::ReadSourceToAttribute(StoredSource::Id source_id) {}

namespace {

base::FilePath DatabasePath(const base::FilePath& user_data_directory) {}

void AssignSourceForDeactivationOrDeletion(
    StoredSource::Id source_id,
    bool has_reports,
    std::vector<StoredSource::Id>& source_ids_to_delete,
    std::vector<StoredSource::Id>& source_ids_to_deactivate) {}

}  // namespace

// static
std::unique_ptr<AttributionStorageSql::Transaction>
AttributionStorageSql::Transaction::CreateAndStart(sql::Database& db) {}

AttributionStorageSql::Transaction::Transaction(sql::Database& db)
    :{}

AttributionStorageSql::Transaction::~Transaction() = default;

bool AttributionStorageSql::Transaction::Commit() {}

AttributionStorageSql::AttributionStorageSql(
    const base::FilePath& user_data_directory,
    AttributionResolverDelegate* delegate)
    :{}

AttributionStorageSql::~AttributionStorageSql() {}

std::unique_ptr<AttributionStorageSql::Transaction>
AttributionStorageSql::StartTransaction() {}

bool AttributionStorageSql::DeactivateSources(
    const std::vector<StoredSource::Id>& sources) {}

bool AttributionStorageSql::DeactivateSourcesForDestinationLimit(
    const std::vector<StoredSource::Id>& sources,
    base::Time now) {}

std::optional<StoredSource> AttributionStorageSql::InsertSource(
    const StorableSource& source,
    base::Time source_time,
    int num_attributions,
    bool event_level_active,
    double randomized_response_rate,
    StoredSource::AttributionLogic attribution_logic,
    base::Time aggregatable_report_window_time) {}

base::expected<std::optional<AttributionStorageSql::ReportIdAndPriority>,
               AttributionStorageSql::Error>
AttributionStorageSql::GetReportWithMinPriority(StoredSource::Id source_id,
                                                base::Time report_time) {}

bool AttributionStorageSql::DeactivateSourceAtEventLevel(StoredSource::Id id) {}

bool AttributionStorageSql::RemoveScopesDataForSource(
    StoredSource::Id source_id) {}

namespace {

// At least 1 destination must always be bound. When there are fewer than 3,
// NULL is used as a placeholder . `A IN (B,C,D)` evaluates to true iff A=B or
// A=C or A=D, since A is always non-NULL. Otherwise, it evaluates to NULL if
// any of B, C, or D is NULL, but that is fine, as the JOIN on the destination
// is only satisfied when the ON clause evaluates to true.
//
// https://www.sqlite.org/lang_expr.html#the_in_and_not_in_operators
void PrepareGetMatchingSourcesStatement(
    sql::Statement& stmt,
    base::span<const net::SchemefulSite> destinations) {}

}  // namespace

bool AttributionStorageSql::UpdateOrRemoveSourcesWithIncompatibleScopeFields(
    const StorableSource& pending_source,
    base::Time source_time) {}

// TODO(apaseltiner): This logic is very similar to that of
// `UpdateOrRemoveSourcesWithIncompatibleScopeFields()`. Can we deduplicate some
// of the logic?
bool AttributionStorageSql::RemoveSourcesWithOutdatedScopes(
    const StorableSource& source,
    base::Time source_time) {}

bool AttributionStorageSql::FindMatchingSourceForTrigger(
    const AttributionTrigger& trigger,
    base::Time trigger_time,
    std::optional<StoredSource::Id>& source_id_to_attribute,
    std::vector<StoredSource::Id>& source_ids_to_delete,
    std::vector<StoredSource::Id>& source_ids_to_deactivate) {}

bool AttributionStorageSql::IncrementNumAttributions(StoredSource::Id id) {}

// Helper to deserialize report rows. See `GetReport()` for the expected
// ordering of columns used for the input to this function.
base::expected<AttributionReport,
               AttributionStorageSql::ReportCorruptionStatusSetAndIds>
AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) {}

std::vector<AttributionReport> AttributionStorageSql::GetAttributionReports(
    base::Time max_report_time,
    int limit) {}

std::optional<base::Time> AttributionStorageSql::GetNextReportTime(
    base::Time time) {}

std::optional<AttributionReport> AttributionStorageSql::GetReport(
    AttributionReport::Id id) {}

bool AttributionStorageSql::DeleteExpiredSources() {}

bool AttributionStorageSql::DeleteReport(AttributionReport::Id report_id) {}

bool AttributionStorageSql::DeleteReportInternal(
    AttributionReport::Id report_id) {}

bool AttributionStorageSql::DeleteEventLevelReportsTriggeredLaterThanForSources(
    const std::vector<StoredSource::Id>& sources,
    base::Time source_time) {}

bool AttributionStorageSql::UpdateReportForSendFailure(
    AttributionReport::Id report_id,
    base::Time new_report_time) {}

bool AttributionStorageSql::AdjustOfflineReportTimes(
    base::TimeDelta min_delay,
    base::TimeDelta max_delay) {}

void AttributionStorageSql::ClearDataWithFilter(
    base::Time delete_begin,
    base::Time delete_end,
    StoragePartition::StorageKeyMatcherFunction filter,
    bool delete_rate_limit_data) {}

void AttributionStorageSql::ClearAllDataAllTime(bool delete_rate_limit_data) {}

int64_t AttributionStorageSql::CountActiveSourcesWithSourceOrigin(
    const SuitableOrigin& origin,
    const base::Time now) {}

int64_t AttributionStorageSql::CountReportsWithDestinationSite(
    const net::SchemefulSite& destination,
    AttributionReport::Type report_type) {}

std::vector<StoredSource> AttributionStorageSql::GetActiveSources(int limit) {}

bool AttributionStorageSql::ReadDedupKeys(
    StoredSource::Id source_id,
    std::vector<uint64_t>& event_level_dedup_keys,
    std::vector<uint64_t>& aggregatable_dedup_keys) {}

bool AttributionStorageSql::StoreDedupKey(StoredSource::Id source_id,
                                          uint64_t dedup_key,
                                          AttributionReport::Type report_type) {}

void AttributionStorageSql::HandleInitializationFailure(
    const InitStatus status) {}

bool AttributionStorageSql::LazyInit(DbCreationPolicy creation_policy) {}

std::optional<int64_t> AttributionStorageSql::NumberOfSources() {}

// Deletes corrupt sources/reports if `deletion_counts` is not `nullptr`.
void AttributionStorageSql::VerifyReports(DeletionCounts* deletion_counts) {}

void AttributionStorageSql::RecordSourcesPerSourceOrigin() {}

bool AttributionStorageSql::InitializeSchema(bool db_empty) {}

bool AttributionStorageSql::CreateSchema() {}

// The interaction between this error callback and `sql::Database` is complex.
// Here are just a few of the sharp edges:
//
// 1. This callback would become reentrant if it called a `sql::Database` method
//    that could encounter an error.
//
// 2. This callback may be invoked multiple times by a single call to a
//    `sql::Database` method.
//
// 3. This callback may see phantom errors that do not otherwise bubble up via
//    return values. This can happen because `sql::Database` runs the error
//    callback eagerly despite the fact that some of its methods ignore certain
//    errors.
//
//    A concrete example: opening the database may run the error callback *and*
//    return true if `sql::Database::Open()` encounters a transient error, but
//    opens the database successfully on the second try.
//
// Reducing this complexity will likely require a redesign of `sql::Database`'s
// error handling interface. See <https://crbug.com/40199997>.
void AttributionStorageSql::DatabaseErrorCallback(int extended_error,
                                                  sql::Statement* stmt) {}

bool AttributionStorageSql::DeleteSources(
    const std::vector<StoredSource::Id>& source_ids) {}

bool AttributionStorageSql::ClearReportsForOriginsInRange(
    base::Time delete_begin,
    base::Time delete_end,
    StoragePartition::StorageKeyMatcherFunction filter,
    std::vector<StoredSource::Id>& source_ids_to_delete,
    int& num_event_reports_deleted,
    int& num_aggregatable_reports_deleted) {}

bool AttributionStorageSql::ClearReportsForSourceIds(
    const std::vector<StoredSource::Id>& source_ids,
    int& num_event_reports_deleted,
    int& num_aggregatable_reports_deleted) {}

RateLimitResult
AttributionStorageSql::AggregatableAttributionAllowedForBudgetLimit(
    const AttributionReport::AggregatableAttributionData&
        aggregatable_attribution,
    int remaining_aggregatable_attribution_budget) {}

bool AttributionStorageSql::AdjustBudgetConsumedForSource(
    StoredSource::Id source_id,
    int additional_budget_consumed) {}

std::optional<AttributionReport::Id>
AttributionStorageSql::StoreAttributionReport(
    StoredSource::Id source_id,
    base::Time trigger_time,
    base::Time initial_report_time,
    const base::Uuid& external_report_id,
    std::optional<uint64_t> trigger_debug_key,
    const SuitableOrigin& context_origin,
    const SuitableOrigin& reporting_origin,
    uint32_t trigger_data,
    int64_t priority) {}

[[nodiscard]] std::optional<AttributionReport::Id>
AttributionStorageSql::StoreNullReport(
    base::Time trigger_time,
    base::Time initial_report_time,
    const base::Uuid& external_report_id,
    std::optional<uint64_t> trigger_debug_key,
    const attribution_reporting::SuitableOrigin& context_origin,
    const attribution_reporting::SuitableOrigin& reporting_origin,
    const std::optional<SuitableOrigin>& coordinator_origin,
    const AggregatableTriggerConfig& trigger_config,
    base::Time fake_source_time) {}

[[nodiscard]] std::optional<AttributionReport::Id>
AttributionStorageSql::StoreAggregatableReport(
    StoredSource::Id source_id,
    base::Time trigger_time,
    base::Time initial_report_time,
    const base::Uuid& external_report_id,
    std::optional<uint64_t> trigger_debug_key,
    const attribution_reporting::SuitableOrigin& context_origin,
    const attribution_reporting::SuitableOrigin& reporting_origin,
    const std::optional<SuitableOrigin>& coordinator_origin,
    const AggregatableTriggerConfig& trigger_config,
    const std::vector<blink::mojom::AggregatableReportHistogramContribution>&
        contributions) {}

std::optional<AttributionReport::Id>
AttributionStorageSql::StoreAttributionReport(
    int64_t source_id,
    base::Time trigger_time,
    base::Time initial_report_time,
    const base::Uuid& external_report_id,
    std::optional<uint64_t> trigger_debug_key,
    const SuitableOrigin& context_origin,
    const SuitableOrigin& reporting_origin,
    AttributionReport::Type report_type,
    const std::string& serialized_metadata) {}

AggregatableResult
AttributionStorageSql::MaybeStoreAggregatableAttributionReportData(
    AttributionReport& report,
    StoredSource::Id source_id,
    int remaining_aggregatable_attribution_budget,
    int num_aggregatable_attribution_reports,
    std::optional<uint64_t> dedup_key,
    std::optional<int>& max_aggregatable_reports_per_source) {}

std::set<AttributionDataModel::DataKey>
AttributionStorageSql::GetAllDataKeys() {}

std::optional<AttributionStorageSql::AggregatableDebugSourceData>
AttributionStorageSql::GetAggregatableDebugSourceData(
    StoredSource::Id source_id) {}

int64_t AttributionStorageSql::StorageFileSizeKB() {}

AggregatableDebugRateLimitTable::Result
AttributionStorageSql::AggregatableDebugReportAllowedForRateLimit(
    const AggregatableDebugReport& report) {}

bool AttributionStorageSql::AdjustAggregatableDebugSourceData(
    StoredSource::Id source_id,
    int additional_budget_consumed) {}

bool AttributionStorageSql::AdjustForAggregatableDebugReport(
    const AggregatableDebugReport& report,
    std::optional<StoredSource::Id> source_id) {}

void AttributionStorageSql::SetDelegate(AttributionResolverDelegate* delegate) {}

bool AttributionStorageSql::AddRateLimitForSource(
    const StoredSource& source,
    int64_t destination_limit_priority) {}

bool AttributionStorageSql::AddRateLimitForAttribution(
    const AttributionInfo& attribution_info,
    const StoredSource& source,
    RateLimitTable::Scope scope,
    AttributionReport::Id id) {}

RateLimitResult AttributionStorageSql::SourceAllowedForReportingOriginLimit(
    const StorableSource& source,
    base::Time source_time) {}

RateLimitResult
AttributionStorageSql::SourceAllowedForReportingOriginPerSiteLimit(
    const StorableSource& source,
    base::Time source_time) {}

RateLimitTable::DestinationRateLimitResult
AttributionStorageSql::SourceAllowedForDestinationRateLimit(
    const StorableSource& source,
    base::Time source_time) {}

RateLimitResult
AttributionStorageSql::SourceAllowedForDestinationPerDayRateLimit(
    const StorableSource& source,
    base::Time source_time) {}

RateLimitResult
AttributionStorageSql::AttributionAllowedForReportingOriginLimit(
    const AttributionInfo& attribution_info,
    const StoredSource& source) {}

RateLimitResult AttributionStorageSql::AttributionAllowedForAttributionLimit(
    const AttributionInfo& attribution_info,
    const StoredSource& source,
    RateLimitTable::Scope scope) {}

base::expected<std::vector<StoredSource::Id>, RateLimitTable::Error>
AttributionStorageSql::GetSourcesToDeactivateForDestinationLimit(
    const StorableSource& source,
    base::Time source_time) {}

bool AttributionStorageSql::DeleteAttributionRateLimit(
    RateLimitTable::Scope scope,
    AttributionReport::Id report_id) {}

}  // namespace content