blob: b6fbe66c36d46b40a72c653bc6f0b07c4a192bb8 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h"
#include <string>
#include <utility>
#include <vector>
#include "base/json/json_writer.h"
#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h"
#include "chrome/browser/safe_browsing/incident_reporting/tracked_preference_incident.h"
#include "components/safe_browsing/proto/csd.pb.h"
#include "services/preferences/public/mojom/tracked_preference_validation_delegate.mojom.h"
namespace safe_browsing {
namespace {
typedef ClientIncidentReport_IncidentData_TrackedPreferenceIncident TPIncident;
typedef ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState
TPIncident_ValueState;
using ValueState =
prefs::mojom::TrackedPreferenceValidationDelegate::ValueState;
// Maps a primary PrefHashStoreTransaction::ValueState and an external
// validation state to a TrackedPreferenceIncident::ValueState.
TPIncident_ValueState MapValueState(
ValueState value_state,
ValueState external_validation_value_state) {
switch (value_state) {
case ValueState::CLEARED:
return TPIncident::CLEARED;
case ValueState::CHANGED:
return TPIncident::CHANGED;
case ValueState::UNTRUSTED_UNKNOWN_VALUE:
return TPIncident::UNTRUSTED_UNKNOWN_VALUE;
default:
switch (external_validation_value_state) {
case ValueState::CLEARED:
return TPIncident::BYPASS_CLEARED;
case ValueState::CHANGED:
return TPIncident::BYPASS_CHANGED;
default:
return TPIncident::UNKNOWN;
}
}
}
} // namespace
PreferenceValidationDelegate::PreferenceValidationDelegate(
Profile* profile,
std::unique_ptr<IncidentReceiver> incident_receiver)
: profile_(profile), incident_receiver_(std::move(incident_receiver)) {}
PreferenceValidationDelegate::~PreferenceValidationDelegate() {
}
void PreferenceValidationDelegate::OnAtomicPreferenceValidation(
const std::string& pref_path,
base::Optional<base::Value> value,
ValueState value_state,
ValueState external_validation_value_state,
bool is_personal) {
TPIncident_ValueState proto_value_state =
MapValueState(value_state, external_validation_value_state);
if (proto_value_state != TPIncident::UNKNOWN) {
std::unique_ptr<TPIncident> incident(
new ClientIncidentReport_IncidentData_TrackedPreferenceIncident());
incident->set_path(pref_path);
if (!value || (!value->GetAsString(incident->mutable_atomic_value()) &&
!base::JSONWriter::Write(
std::move(*value), incident->mutable_atomic_value()))) {
incident->clear_atomic_value();
}
incident->set_value_state(proto_value_state);
incident_receiver_->AddIncidentForProfile(
profile_, std::make_unique<TrackedPreferenceIncident>(
std::move(incident), is_personal));
}
}
void PreferenceValidationDelegate::OnSplitPreferenceValidation(
const std::string& pref_path,
const std::vector<std::string>& invalid_keys,
const std::vector<std::string>& external_validation_invalid_keys,
ValueState value_state,
ValueState external_validation_value_state,
bool is_personal) {
TPIncident_ValueState proto_value_state =
MapValueState(value_state, external_validation_value_state);
if (proto_value_state != TPIncident::UNKNOWN) {
std::unique_ptr<ClientIncidentReport_IncidentData_TrackedPreferenceIncident>
incident(
new ClientIncidentReport_IncidentData_TrackedPreferenceIncident());
incident->set_path(pref_path);
if (proto_value_state == TPIncident::BYPASS_CLEARED ||
proto_value_state == TPIncident::BYPASS_CHANGED) {
for (auto scan(external_validation_invalid_keys.begin());
scan != external_validation_invalid_keys.end(); ++scan) {
incident->add_split_key(*scan);
}
} else {
for (auto scan(invalid_keys.begin()); scan != invalid_keys.end();
++scan) {
incident->add_split_key(*scan);
}
}
incident->set_value_state(proto_value_state);
incident_receiver_->AddIncidentForProfile(
profile_, std::make_unique<TrackedPreferenceIncident>(
std::move(incident), is_personal));
}
}
} // namespace safe_browsing