blob: 107f0f73e1f601046effb278fd36ade7bc594b84 [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.
// Test support library for response payloads.
#include "chrome/browser/policy/messaging_layer/util/test_response_payload.h"
#include "base/base64.h"
#include "base/strings/strcat.h"
#include "base/values.h"
#include "chrome/browser/policy/messaging_layer/util/reporting_server_connector.h"
#include "components/reporting/util/encrypted_reporting_json_keys.h"
#include "components/reporting/util/status.h"
#include "components/reporting/util/statusor.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace reporting {
ResponseBuilder::ResponseBuilder(const base::Value::Dict& request)
: request_(request.Clone()) {}
ResponseBuilder::ResponseBuilder(base::Value::Dict&& request)
: request_(std::move(request)) {}
ResponseBuilder::ResponseBuilder(const ResponseBuilder& other)
: request_(other.request_.Clone()), params_(other.params_) {}
ResponseBuilder& ResponseBuilder::SetForceConfirm(bool force_confirm) {
params_.force_confirm = force_confirm;
return *this;
}
ResponseBuilder& ResponseBuilder::SetNull(bool null) {
params_.null = null;
return *this;
}
ResponseBuilder& ResponseBuilder::SetRequest(const base::Value::Dict& request) {
request_ = request.Clone();
return *this;
}
ResponseBuilder& ResponseBuilder::SetRequest(base::Value::Dict&& request) {
request_ = std::move(request);
return *this;
}
ResponseBuilder& ResponseBuilder::SetSuccess(bool success) {
params_.success = success;
return *this;
}
StatusOr<base::Value::Dict> ResponseBuilder::Build() const {
if (params_.null) {
return base::unexpected(
Status(error::FAILED_PRECONDITION, "No parameters set"));
}
base::Value::Dict response;
// Attach sequenceInformation.
if (const base::Value::List* const encrypted_record_list =
request_.FindList(json_keys::kEncryptedRecordList);
encrypted_record_list != nullptr) {
EXPECT_FALSE(encrypted_record_list->empty());
// Retrieve and process sequence information. The last record is the last
// successfully uploaded record if the response is successful, or the first
// failed record if the response is failure.
const auto seq_info_it = std::prev(encrypted_record_list->cend());
const auto* const seq_info =
seq_info_it->GetDict().FindDict(json_keys::kSequenceInformation);
EXPECT_NE(seq_info, nullptr);
if (params_.success) {
response.Set(json_keys::kLastSucceedUploadedRecord, seq_info->Clone());
} else {
response.Set(json_keys::kFirstFailedUploadedRecord,
base::Value::Dict().Set(json_keys::kFailedUploadedRecord,
seq_info->Clone()));
response.Set(json_keys::kFirstFailedUploadedRecord,
base::Value::Dict().Set(
json_keys::kFailureStatus,
base::Value::Dict().Set(json_keys::kErrorCode, 12345)));
response.Set(json_keys::kFirstFailedUploadedRecord,
base::Value::Dict().Set(
json_keys::kFailureStatus,
base::Value::Dict().Set(json_keys::kErrorCode,
"You've got a fake error.")));
const auto* const last_success_seq_info =
std::prev(seq_info_it)
->GetDict()
.FindDict(json_keys::kSequenceInformation);
EXPECT_NE(last_success_seq_info, nullptr);
response.Set(json_keys::kLastSucceedUploadedRecord,
last_success_seq_info->Clone());
}
}
// If forceConfirm confirm is expected, set it.
if (params_.force_confirm) {
response.Set(json_keys::kForceConfirm, true);
}
// If attach_encryption_settings is true, process that.
const auto attach_encryption_settings =
request_.FindBool(json_keys::kAttachEncryptionSettings);
if (attach_encryption_settings.has_value() &&
attach_encryption_settings.value()) {
base::Value::Dict encryption_settings;
std::string encoded = base::Base64Encode("PUBLIC KEY");
encryption_settings.Set(json_keys::kPublicKey, std::move(encoded));
encryption_settings.Set(json_keys::kPublicKeyId, 12345);
encryption_settings.Set(json_keys::kPublicKeySignature,
base::Base64Encode("PUBLIC KEY SIG"));
response.Set(json_keys::kEncryptionSettings,
std::move(encryption_settings));
}
// If configurationFileVersion is provided, attach the configuration file.
const auto configuration_file_version =
request_.FindInt(json_keys::kConfigurationFileVersion);
if (configuration_file_version.has_value()) {
base::Value::Dict configuration_file;
base::Value::List event_configs;
base::Value::Dict heartbeat;
heartbeat.Set(json_keys::kConfigurationFileDestination, "HEARTBEAT_EVENTS");
heartbeat.Set(json_keys::kConfigurationFileMinimumReleaseVersion, 11111);
event_configs.Append(std::move(heartbeat));
base::Value::Dict login;
login.Set(json_keys::kConfigurationFileDestination, "LOGIN_LOGOUT_EVENTS");
login.Set(json_keys::kConfigurationFileMinimumReleaseVersion, 22222);
login.Set(json_keys::kConfigurationFileMaximumReleaseVersion, 33333);
event_configs.Append(std::move(login));
base::Value::Dict lock;
lock.Set(json_keys::kConfigurationFileDestination, "LOCK_UNLOCK_EVENTS");
event_configs.Append(std::move(lock));
std::string encoded = base::Base64Encode("Fake signature");
configuration_file.Set(json_keys::kConfigurationFileSignature,
base::Base64Encode("Fake signature"));
configuration_file.Set(json_keys::kBlockedEventConfigs,
std::move(event_configs));
configuration_file.Set(json_keys::kConfigurationFileVersionResponse,
123456);
response.Set(json_keys::kConfigurationFile, std::move(configuration_file));
}
return response;
}
MakeUploadEncryptedReportAction::MakeUploadEncryptedReportAction(
ResponseBuilder&& response_builder)
: response_builder_(std::move(response_builder)) {}
void MakeUploadEncryptedReportAction::operator()(
base::Value::Dict request,
std::optional<base::Value::Dict> context,
ReportingServerConnector::ResponseCallback callback) {
response_builder_.SetRequest(std::move(request));
auto response_result = response_builder_.Build();
if (!response_result.has_value()) {
std::move(callback).Run(base::unexpected(response_result.error()));
return;
}
UploadResponseParser response_parser(
EncryptedReportingClient::GenerationGuidIsRequired(),
std::move(response_result.value()));
std::move(callback).Run(std::move(response_parser));
}
} // namespace reporting