Commit 711711f0 authored by Zach Trudo's avatar Zach Trudo Committed by Commit Bot

Add UploadEncryptedReport CloudPolicyClient call

Call for uploading EncryptedReportingJobConfiguration jobs.

Bug: chromium:1078512
Change-Id: Ib8018b4eed4392bbeccdae96a5924a2ed6411b8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2499073
Commit-Queue: Zach Trudo <zatrudo@google.com>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825637}
parent 3bfadad2
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "components/policy/core/common/cloud/device_management_service.h" #include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/dm_auth.h" #include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/dmserver_job_configurations.h" #include "components/policy/core/common/cloud/dmserver_job_configurations.h"
#include "components/policy/core/common/cloud/encrypted_reporting_job_configuration.h"
#include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h" #include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h"
#include "components/policy/core/common/cloud/signing_service.h" #include "components/policy/core/common/cloud/signing_service.h"
#include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_constants.h"
...@@ -601,6 +602,30 @@ void CloudPolicyClient::UploadSecurityEventReport(base::Value report, ...@@ -601,6 +602,30 @@ void CloudPolicyClient::UploadSecurityEventReport(base::Value report,
add_connector_url_params_, std::move(callback)); add_connector_url_params_, std::move(callback));
} }
void CloudPolicyClient::UploadEncryptedReport(
const ::reporting::EncryptedRecord& record,
base::Optional<base::Value> context,
StatusCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!is_registered()) {
std::move(callback).Run(false);
return;
}
std::unique_ptr<EncryptedReportingJobConfiguration> config =
std::make_unique<EncryptedReportingJobConfiguration>(
this, service()->configuration()->GetEncryptedReportingServerUrl(),
base::BindOnce(&CloudPolicyClient::OnEncryptedReportUploadCompleted,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
if (!config->AddEncryptedRecord(record)) {
return;
}
if (context.has_value()) {
config->UpdateContext(context.value());
}
request_jobs_.push_back(service_->CreateJob(std::move(config)));
}
void CloudPolicyClient::UploadAppInstallReport(base::Value report, void CloudPolicyClient::UploadAppInstallReport(base::Value report,
StatusCallback callback) { StatusCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
...@@ -1254,6 +1279,24 @@ void CloudPolicyClient::OnRealtimeReportUploadCompleted( ...@@ -1254,6 +1279,24 @@ void CloudPolicyClient::OnRealtimeReportUploadCompleted(
RemoveJob(job); RemoveJob(job);
} }
// |job| can be null if the owning EncryptedReportingJobConfiguration is
// destroyed prior to calling OnUploadComplete. In that case, callback will be
// called with false value.
void CloudPolicyClient::OnEncryptedReportUploadCompleted(
StatusCallback callback,
DeviceManagementService::Job* job,
DeviceManagementStatus status,
int net_error,
const base::Value& response) {
if (job == nullptr) {
std::move(callback).Run(false);
return;
}
OnRealtimeReportUploadCompleted(std::move(callback), job, status, net_error,
response);
}
void CloudPolicyClient::OnRemoteCommandsFetched( void CloudPolicyClient::OnRemoteCommandsFetched(
RemoteCommandCallback callback, RemoteCommandCallback callback,
DeviceManagementService::Job* job, DeviceManagementService::Job* job,
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "components/policy/core/common/remote_commands/remote_command_job.h" #include "components/policy/core/common/remote_commands/remote_command_job.h"
#include "components/policy/policy_export.h" #include "components/policy/policy_export.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "components/policy/proto/record.pb.h"
namespace network { namespace network {
class SharedURLLoaderFactory; class SharedURLLoaderFactory;
...@@ -308,6 +309,13 @@ class POLICY_EXPORT CloudPolicyClient { ...@@ -308,6 +309,13 @@ class POLICY_EXPORT CloudPolicyClient {
virtual void UploadSecurityEventReport(base::Value report, virtual void UploadSecurityEventReport(base::Value report,
StatusCallback callback); StatusCallback callback);
// Uploads a report containing an EncryptedRecord. The client must be in a
// registered state. The |callback| will be called when the operation
// completes.
virtual void UploadEncryptedReport(const ::reporting::EncryptedRecord& record,
base::Optional<base::Value> context,
StatusCallback callback);
// Uploads a report on the status of app push-installs. The client must be in // Uploads a report on the status of app push-installs. The client must be in
// a registered state. The |callback| will be called when the operation // a registered state. The |callback| will be called when the operation
// completes. // completes.
...@@ -633,6 +641,13 @@ class POLICY_EXPORT CloudPolicyClient { ...@@ -633,6 +641,13 @@ class POLICY_EXPORT CloudPolicyClient {
int net_error, int net_error,
const base::Value& response); const base::Value& response);
// Callback for encrypted report upload requests.
void OnEncryptedReportUploadCompleted(StatusCallback callback,
DeviceManagementService::Job* job,
DeviceManagementStatus status,
int net_error,
const base::Value& response);
// Callback for remote command fetch requests. // Callback for remote command fetch requests.
void OnRemoteCommandsFetched( void OnRemoteCommandsFetched(
RemoteCommandCallback callback, RemoteCommandCallback callback,
......
...@@ -513,6 +513,15 @@ class CloudPolicyClientTest : public testing::Test { ...@@ -513,6 +513,15 @@ class CloudPolicyClientTest : public testing::Test {
net::OK, DeviceManagementService::kSuccess, "{}"))); net::OK, DeviceManagementService::kSuccess, "{}")));
} }
void ExpectEncryptedReport() {
EXPECT_CALL(service_, StartJob(_))
.WillOnce(DoAll(service_.CaptureJobType(&job_type_),
service_.CaptureQueryParams(&query_params_),
service_.CapturePayload(&job_payload_),
service_.StartJobAsync(
net::OK, DeviceManagementService::kSuccess, "{}")));
}
void ExpectFetchRemoteCommands( void ExpectFetchRemoteCommands(
const em::DeviceManagementResponse& remote_command_response) { const em::DeviceManagementResponse& remote_command_response) {
EXPECT_CALL(service_, StartJob(_)) EXPECT_CALL(service_, StartJob(_))
...@@ -577,6 +586,17 @@ class CloudPolicyClientTest : public testing::Test { ...@@ -577,6 +586,17 @@ class CloudPolicyClientTest : public testing::Test {
return policy_data.SerializeAsString(); return policy_data.SerializeAsString();
} }
void AttemptUploadEncryptedWaitUntilIdle(
const ::reporting::EncryptedRecord& record,
base::Optional<base::Value> context = base::nullopt) {
CloudPolicyClient::StatusCallback callback =
base::BindOnce(&MockStatusCallbackObserver::OnCallbackComplete,
base::Unretained(&callback_observer_));
client_->UploadEncryptedReport(record, std::move(context),
std::move(callback));
base::RunLoop().RunUntilIdle();
}
// Request protobufs used as expectations for the client requests. // Request protobufs used as expectations for the client requests.
em::DeviceManagementRequest registration_request_; em::DeviceManagementRequest registration_request_;
em::DeviceManagementRequest reregistration_request_; em::DeviceManagementRequest reregistration_request_;
...@@ -1638,6 +1658,65 @@ TEST_F(CloudPolicyClientTest, RealtimeReportMerge) { ...@@ -1638,6 +1658,65 @@ TEST_F(CloudPolicyClientTest, RealtimeReportMerge) {
.size()); .size());
} }
TEST_F(CloudPolicyClientTest, UploadEncryptedReport) {
// Create record
::reporting::EncryptedRecord record;
record.set_encrypted_wrapped_record("Enterprise");
auto* sequencing_information = record.mutable_sequencing_information();
sequencing_information->set_sequencing_id(1701);
sequencing_information->set_generation_id(12345678);
sequencing_information->set_priority(::reporting::IMMEDIATE);
RegisterClient();
ExpectEncryptedReport();
EXPECT_CALL(callback_observer_, OnCallbackComplete(true)).Times(1);
AttemptUploadEncryptedWaitUntilIdle(record);
EXPECT_EQ(
job_type_,
DeviceManagementService::JobConfiguration::TYPE_UPLOAD_ENCRYPTED_REPORT);
EXPECT_EQ(client_->status(), DM_STATUS_SUCCESS);
}
TEST_F(CloudPolicyClientTest, DenyPoorlyFormedEncryptedRecords) {
RegisterClient();
// Create empty record
::reporting::EncryptedRecord record;
EXPECT_CALL(callback_observer_, OnCallbackComplete(false)).Times(4);
AttemptUploadEncryptedWaitUntilIdle(record);
// Add encrypted_wrapped_record without sequencing information.
record.set_encrypted_wrapped_record("Enterprise");
AttemptUploadEncryptedWaitUntilIdle(record);
// Incorrectly set sequencing information by only setting sequencing id.
auto* sequencing_information = record.mutable_sequencing_information();
sequencing_information->set_sequencing_id(1701);
AttemptUploadEncryptedWaitUntilIdle(record);
// Finish correctly setting sequencing information but incorrectly set
// encryption info.
sequencing_information->set_generation_id(12345678);
sequencing_information->set_priority(::reporting::IMMEDIATE);
auto* encryption_info = record.mutable_encryption_info();
encryption_info->set_encryption_key("Key");
AttemptUploadEncryptedWaitUntilIdle(record);
// Finish correctly setting encryption info - expect complete call.
encryption_info->set_public_key_id(1234);
EXPECT_CALL(callback_observer_, OnCallbackComplete(true)).Times(1);
ExpectEncryptedReport();
AttemptUploadEncryptedWaitUntilIdle(record);
}
TEST_F(CloudPolicyClientTest, UploadAppInstallReport) { TEST_F(CloudPolicyClientTest, UploadAppInstallReport) {
RegisterClient(); RegisterClient();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment