blob: 4dd665cf8c71346bb94ead3a74e0c3a5f82e6d81 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/attribution_reporting/attribution_scopes_data.h"
#include <stdint.h>
#include <optional>
#include <utility>
#include "base/check.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "base/values.h"
#include "components/attribution_reporting/attribution_scopes_set.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/parsing_utils.h"
#include "components/attribution_reporting/privacy_math.h"
#include "components/attribution_reporting/source_registration_error.mojom.h"
namespace attribution_reporting {
namespace {
using ::attribution_reporting::mojom::SourceRegistrationError;
bool ScopesValid(const AttributionScopesSet& scopes, uint32_t scope_limit) {
return !scopes.scopes().empty() && scopes.IsValidForSource(scope_limit);
}
bool EventStatesValid(uint32_t max_event_states) {
return max_event_states > 0 &&
max_event_states <= MaxTriggerStateCardinality();
}
bool DataValid(const AttributionScopesSet& scopes_set,
uint32_t scope_limit,
uint32_t max_event_states) {
return scope_limit > 0 && ScopesValid(scopes_set, scope_limit) &&
EventStatesValid(max_event_states);
}
} // namespace
// static
std::optional<AttributionScopesData> AttributionScopesData::Create(
AttributionScopesSet attribution_scopes_set,
uint32_t attribution_scope_limit,
uint32_t max_event_states) {
if (!DataValid(attribution_scopes_set, attribution_scope_limit,
max_event_states)) {
return std::nullopt;
}
return AttributionScopesData(std::move(attribution_scopes_set),
attribution_scope_limit, max_event_states);
}
// static
base::expected<AttributionScopesData, SourceRegistrationError>
AttributionScopesData::FromJSON(base::Value& v) {
base::Value::Dict* scopes_dict = v.GetIfDict();
if (!scopes_dict) {
return base::unexpected(SourceRegistrationError::kAttributionScopesInvalid);
}
uint32_t attribution_scope_limit;
if (const base::Value* attribution_scope_limit_value =
scopes_dict->Find(kLimit)) {
ASSIGN_OR_RETURN(
attribution_scope_limit,
ParsePositiveUint32(*attribution_scope_limit_value), [](ParseError) {
return SourceRegistrationError::kAttributionScopeLimitInvalid;
});
} else {
return base::unexpected(
SourceRegistrationError::kAttributionScopeLimitRequired);
}
uint32_t max_event_states = kDefaultMaxEventStates;
if (const base::Value* event_states_value =
scopes_dict->Find(kMaxEventStates)) {
ASSIGN_OR_RETURN(max_event_states, ParsePositiveUint32(*event_states_value),
[](ParseError) {
return SourceRegistrationError::kMaxEventStatesInvalid;
});
if (max_event_states > MaxTriggerStateCardinality()) {
return base::unexpected(SourceRegistrationError::kMaxEventStatesInvalid);
}
}
ASSIGN_OR_RETURN(
AttributionScopesSet attribution_scopes,
AttributionScopesSet::FromJSON(*scopes_dict, attribution_scope_limit));
return AttributionScopesData(std::move(attribution_scopes),
attribution_scope_limit, max_event_states);
}
AttributionScopesData::AttributionScopesData(AttributionScopesSet scopes,
uint32_t attribution_scope_limit,
uint32_t max_event_states)
: attribution_scopes_set_(std::move(scopes)),
attribution_scope_limit_(attribution_scope_limit),
max_event_states_(max_event_states) {
CHECK(DataValid(attribution_scopes_set_, attribution_scope_limit_,
max_event_states_));
}
AttributionScopesData::AttributionScopesData(mojo::DefaultConstruct::Tag) {
CHECK(!DataValid(attribution_scopes_set_, attribution_scope_limit_,
max_event_states_));
}
AttributionScopesData::~AttributionScopesData() = default;
AttributionScopesData::AttributionScopesData(const AttributionScopesData&) =
default;
AttributionScopesData::AttributionScopesData(AttributionScopesData&&) = default;
AttributionScopesData& AttributionScopesData::operator=(
const AttributionScopesData&) = default;
AttributionScopesData& AttributionScopesData::operator=(
AttributionScopesData&&) = default;
base::Value::Dict AttributionScopesData::ToJson() const {
base::Value::Dict dict;
dict.Set(kLimit, Uint32ToJson(attribution_scope_limit_));
dict.Set(kMaxEventStates, Uint32ToJson(max_event_states_));
attribution_scopes_set_.SerializeForSource(dict);
return dict;
}
} // namespace attribution_reporting