Commit 0a5685cf authored by Nikita Podguzov's avatar Nikita Podguzov Committed by Commit Bot

Fetch External Policy for Device Settings.

Add support for External Data referenced by Device Policy.
Use the new support to implement the DeviceNativePrinters policy.
Add browser test verifying external data cache is cleaned up after policy was changed or removed.

Bug: 807068
Change-Id: Ib98778a438e929a78214d1d9ab066a41a6bdcf09
Reviewed-on: https://chromium-review.googlesource.com/c/1335592
Commit-Queue: Nikita Podguzov <nikitapodguzov@google.com>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610596}
parent 7564c931
...@@ -1500,6 +1500,8 @@ source_set("chromeos") { ...@@ -1500,6 +1500,8 @@ source_set("chromeos") {
"policy/device_local_account_policy_store.h", "policy/device_local_account_policy_store.h",
"policy/device_network_configuration_updater.cc", "policy/device_network_configuration_updater.cc",
"policy/device_network_configuration_updater.h", "policy/device_network_configuration_updater.h",
"policy/device_policy_cloud_external_data_manager.cc",
"policy/device_policy_cloud_external_data_manager.h",
"policy/device_policy_decoder_chromeos.cc", "policy/device_policy_decoder_chromeos.cc",
"policy/device_policy_decoder_chromeos.h", "policy/device_policy_decoder_chromeos.h",
"policy/device_policy_remover.h", "policy/device_policy_remover.h",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
#include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
#include "chrome/browser/chromeos/policy/device_network_configuration_updater.h" #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
#include "chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.h"
#include "chrome/browser/chromeos/policy/enrollment_config.h" #include "chrome/browser/chromeos/policy/enrollment_config.h"
#include "chrome/browser/chromeos/policy/hostname_handler.h" #include "chrome/browser/chromeos/policy/hostname_handler.h"
#include "chrome/browser/chromeos/policy/minimum_version_policy_handler.h" #include "chrome/browser/chromeos/policy/minimum_version_policy_handler.h"
...@@ -40,6 +42,7 @@ ...@@ -40,6 +42,7 @@
#include "chrome/browser/policy/device_management_service_configuration.h" #include "chrome/browser/policy/device_management_service_configuration.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chromeos/attestation/attestation_flow.h" #include "chromeos/attestation/attestation_flow.h"
#include "chromeos/chromeos_paths.h"
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
#include "chromeos/cryptohome/async_method_caller.h" #include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/cryptohome/system_salt_getter.h" #include "chromeos/cryptohome/system_salt_getter.h"
...@@ -56,7 +59,9 @@ ...@@ -56,7 +59,9 @@
#include "chromeos/system/statistics_provider.h" #include "chromeos/system/statistics_provider.h"
#include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
#include "components/policy/core/common/cloud/resource_cache.h"
#include "components/policy/core/common/proxy_policy_provider.h" #include "components/policy/core/common/proxy_policy_provider.h"
#include "components/policy/policy_constants.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_auth_util.h"
...@@ -123,9 +128,20 @@ BrowserPolicyConnectorChromeOS::BrowserPolicyConnectorChromeOS() ...@@ -123,9 +128,20 @@ BrowserPolicyConnectorChromeOS::BrowserPolicyConnectorChromeOS()
state_keys_broker_ = std::make_unique<ServerBackedStateKeysBroker>( state_keys_broker_ = std::make_unique<ServerBackedStateKeysBroker>(
chromeos::DBusThreadManager::Get()->GetSessionManagerClient()); chromeos::DBusThreadManager::Get()->GetSessionManagerClient());
base::FilePath device_policy_external_data_path;
CHECK(base::PathService::Get(chromeos::DIR_DEVICE_POLICY_EXTERNAL_DATA,
&device_policy_external_data_path));
auto external_data_manager =
std::make_unique<DevicePolicyCloudExternalDataManager>(
base::BindRepeating(&GetChromePolicyDetails),
GetBackgroundTaskRunner(), device_policy_external_data_path,
device_cloud_policy_store.get());
device_cloud_policy_manager_ = new DeviceCloudPolicyManagerChromeOS( device_cloud_policy_manager_ = new DeviceCloudPolicyManagerChromeOS(
std::move(device_cloud_policy_store), std::move(device_cloud_policy_store),
base::ThreadTaskRunnerHandle::Get(), state_keys_broker_.get()); std::move(external_data_manager), base::ThreadTaskRunnerHandle::Get(),
state_keys_broker_.get());
providers_for_init_.push_back( providers_for_init_.push_back(
base::WrapUnique<ConfigurationPolicyProvider>( base::WrapUnique<ConfigurationPolicyProvider>(
device_cloud_policy_manager_)); device_cloud_policy_manager_));
......
...@@ -7,9 +7,15 @@ ...@@ -7,9 +7,15 @@
#include <utility> #include <utility>
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "components/policy/core/common/cloud/cloud_external_data_manager.h" #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h" #include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h" #include "components/policy/core/common/cloud/cloud_policy_store.h"
...@@ -17,7 +23,9 @@ ...@@ -17,7 +23,9 @@
#include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h" #include "components/policy/core/common/policy_types.h"
#include "crypto/sha2.h" #include "crypto/sha2.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace policy { namespace policy {
namespace test { namespace test {
...@@ -40,6 +48,27 @@ std::unique_ptr<base::DictionaryValue> ConstructExternalDataReference( ...@@ -40,6 +48,27 @@ std::unique_ptr<base::DictionaryValue> ConstructExternalDataReference(
return metadata; return metadata;
} }
std::string ConstructExternalDataPolicy(
const net::test_server::EmbeddedTestServer& test_server,
const std::string& external_data_path) {
std::string url =
test_server.GetURL(std::string("/") + external_data_path).spec();
std::string external_data;
base::FilePath test_data_dir;
EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
{
base::ScopedAllowBlockingForTesting allow_blocking;
EXPECT_TRUE(base::ReadFileToString(
test_data_dir.AppendASCII(external_data_path), &external_data));
}
std::string policy;
EXPECT_TRUE(base::JSONWriter::Write(
*ConstructExternalDataReference(url, external_data), &policy));
return policy;
}
void SetExternalDataReference(CloudPolicyCore* core, void SetExternalDataReference(CloudPolicyCore* core,
const std::string& policy, const std::string& policy,
std::unique_ptr<base::DictionaryValue> metadata) { std::unique_ptr<base::DictionaryValue> metadata) {
......
...@@ -14,6 +14,12 @@ namespace base { ...@@ -14,6 +14,12 @@ namespace base {
class DictionaryValue; class DictionaryValue;
} }
namespace net {
namespace test_server {
class EmbeddedTestServer;
}
} // namespace net
namespace policy { namespace policy {
class CloudPolicyCore; class CloudPolicyCore;
...@@ -32,6 +38,12 @@ std::unique_ptr<base::DictionaryValue> ConstructExternalDataReference( ...@@ -32,6 +38,12 @@ std::unique_ptr<base::DictionaryValue> ConstructExternalDataReference(
const std::string& url, const std::string& url,
const std::string& data); const std::string& data);
// Constructs the external data policy from the content of the file located on
// |external_data_path|.
std::string ConstructExternalDataPolicy(
const net::test_server::EmbeddedTestServer& test_server,
const std::string& external_data_path);
// TODO(bartfab): Makes an arbitrary |policy| in |core| reference external data // TODO(bartfab): Makes an arbitrary |policy| in |core| reference external data
// as specified in |metadata|. This is only done because there are no policies // as specified in |metadata|. This is only done because there are no policies
// that reference external data yet. Once the first such policy is added, it // that reference external data yet. Once the first such policy is added, it
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
#include "chromeos/settings/install_attributes.h" #include "chromeos/settings/install_attributes.h"
#include "chromeos/system/statistics_provider.h" #include "chromeos/system/statistics_provider.h"
#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h" #include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/cloud_policy_service.h" #include "components/policy/core/common/cloud/cloud_policy_service.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h" #include "components/policy/core/common/cloud/cloud_policy_store.h"
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
#include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_instance.h"
#include "crypto/sha2.h" #include "crypto/sha2.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace em = enterprise_management; namespace em = enterprise_management;
...@@ -109,6 +111,7 @@ bool ForcedReEnrollmentEnabled() { ...@@ -109,6 +111,7 @@ bool ForcedReEnrollmentEnabled() {
DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS( DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store, std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store,
std::unique_ptr<CloudExternalDataManager> external_data_manager,
const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner,
ServerBackedStateKeysBroker* state_keys_broker) ServerBackedStateKeysBroker* state_keys_broker)
: CloudPolicyManager( : CloudPolicyManager(
...@@ -118,6 +121,7 @@ DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS( ...@@ -118,6 +121,7 @@ DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
task_runner, task_runner,
base::BindRepeating(&content::GetNetworkConnectionTracker)), base::BindRepeating(&content::GetNetworkConnectionTracker)),
device_store_(std::move(store)), device_store_(std::move(store)),
external_data_manager_(std::move(external_data_manager)),
state_keys_broker_(state_keys_broker), state_keys_broker_(state_keys_broker),
task_runner_(task_runner), task_runner_(task_runner),
local_state_(nullptr) {} local_state_(nullptr) {}
...@@ -199,6 +203,7 @@ void DeviceCloudPolicyManagerChromeOS::Shutdown() { ...@@ -199,6 +203,7 @@ void DeviceCloudPolicyManagerChromeOS::Shutdown() {
syslog_uploader_.reset(); syslog_uploader_.reset();
heartbeat_scheduler_.reset(); heartbeat_scheduler_.reset();
state_keys_update_subscription_.reset(); state_keys_update_subscription_.reset();
external_data_manager_->Disconnect();
CloudPolicyManager::Shutdown(); CloudPolicyManager::Shutdown();
signin_profile_forwarding_schema_registry_.reset(); signin_profile_forwarding_schema_registry_.reset();
} }
...@@ -270,6 +275,9 @@ void DeviceCloudPolicyManagerChromeOS::StartConnection( ...@@ -270,6 +275,9 @@ void DeviceCloudPolicyManagerChromeOS::StartConnection(
core()->TrackRefreshDelayPref(local_state_, core()->TrackRefreshDelayPref(local_state_,
prefs::kDevicePolicyRefreshRate); prefs::kDevicePolicyRefreshRate);
external_data_manager_->Connect(
g_browser_process->shared_url_loader_factory());
enrollment_policy_observer_.reset( enrollment_policy_observer_.reset(
new chromeos::attestation::EnrollmentPolicyObserver(client())); new chromeos::attestation::EnrollmentPolicyObserver(client()));
......
...@@ -63,6 +63,7 @@ class DeviceCloudPolicyManagerChromeOS : public CloudPolicyManager { ...@@ -63,6 +63,7 @@ class DeviceCloudPolicyManagerChromeOS : public CloudPolicyManager {
// upload tasks. // upload tasks.
DeviceCloudPolicyManagerChromeOS( DeviceCloudPolicyManagerChromeOS(
std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store, std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store,
std::unique_ptr<CloudExternalDataManager> external_data_manager,
const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner,
ServerBackedStateKeysBroker* state_keys_broker); ServerBackedStateKeysBroker* state_keys_broker);
~DeviceCloudPolicyManagerChromeOS() override; ~DeviceCloudPolicyManagerChromeOS() override;
...@@ -154,6 +155,10 @@ class DeviceCloudPolicyManagerChromeOS : public CloudPolicyManager { ...@@ -154,6 +155,10 @@ class DeviceCloudPolicyManagerChromeOS : public CloudPolicyManager {
// Points to the same object as the base CloudPolicyManager::store(), but with // Points to the same object as the base CloudPolicyManager::store(), but with
// actual device policy specific type. // actual device policy specific type.
std::unique_ptr<DeviceCloudPolicyStoreChromeOS> device_store_; std::unique_ptr<DeviceCloudPolicyStoreChromeOS> device_store_;
// Manages external data referenced by device policies.
std::unique_ptr<CloudExternalDataManager> external_data_manager_;
ServerBackedStateKeysBroker* state_keys_broker_; ServerBackedStateKeysBroker* state_keys_broker_;
// Helper object that handles updating the server with our current device // Helper object that handles updating the server with our current device
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h" #include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h"
#include "components/policy/core/common/cloud/mock_device_management_service.h" #include "components/policy/core/common/cloud/mock_device_management_service.h"
#include "components/policy/core/common/cloud/mock_signing_service.h" #include "components/policy/core/common/cloud/mock_signing_service.h"
#include "components/policy/core/common/external_data_fetcher.h" #include "components/policy/core/common/external_data_fetcher.h"
...@@ -105,9 +106,11 @@ class TestingDeviceCloudPolicyManagerChromeOS ...@@ -105,9 +106,11 @@ class TestingDeviceCloudPolicyManagerChromeOS
public: public:
TestingDeviceCloudPolicyManagerChromeOS( TestingDeviceCloudPolicyManagerChromeOS(
std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store, std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store,
std::unique_ptr<CloudExternalDataManager> external_data_manager,
const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner,
ServerBackedStateKeysBroker* state_keys_broker) ServerBackedStateKeysBroker* state_keys_broker)
: DeviceCloudPolicyManagerChromeOS(std::move(store), : DeviceCloudPolicyManagerChromeOS(std::move(store),
std::move(external_data_manager),
task_runner, task_runner,
state_keys_broker) { state_keys_broker) {
set_component_policy_disabled_for_testing(true); set_component_policy_disabled_for_testing(true);
...@@ -157,8 +160,9 @@ class DeviceCloudPolicyManagerChromeOSTest ...@@ -157,8 +160,9 @@ class DeviceCloudPolicyManagerChromeOSTest
&device_settings_service_, install_attributes_.get(), &device_settings_service_, install_attributes_.get(),
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get());
manager_ = std::make_unique<TestingDeviceCloudPolicyManagerChromeOS>( manager_ = std::make_unique<TestingDeviceCloudPolicyManagerChromeOS>(
base::WrapUnique(store_), base::ThreadTaskRunnerHandle::Get(), base::WrapUnique(store_),
&state_keys_broker_); std::make_unique<MockCloudExternalDataManager>(),
base::ThreadTaskRunnerHandle::Get(), &state_keys_broker_);
RegisterLocalState(local_state_.registry()); RegisterLocalState(local_state_.registry());
manager_->Init(&schema_registry_); manager_->Init(&schema_registry_);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chrome/browser/chromeos/policy/value_validation/onc_device_policy_value_validator.h" #include "chrome/browser/chromeos/policy/value_validation/onc_device_policy_value_validator.h"
#include "chromeos/settings/install_attributes.h" #include "chromeos/settings/install_attributes.h"
#include "components/ownership/owner_key_util.h" #include "components/ownership/owner_key_util.h"
#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/proto/chrome_device_policy.pb.h" #include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
...@@ -168,7 +169,7 @@ void DeviceCloudPolicyStoreChromeOS::UpdateFromService() { ...@@ -168,7 +169,7 @@ void DeviceCloudPolicyStoreChromeOS::UpdateFromService() {
PolicyMap new_policy_map; PolicyMap new_policy_map;
if (is_managed()) { if (is_managed()) {
DecodeDevicePolicy(*device_settings_service_->device_settings(), DecodeDevicePolicy(*device_settings_service_->device_settings(),
&new_policy_map); external_data_manager(), &new_policy_map);
} }
policy_map_.Swap(&new_policy_map); policy_map_.Swap(&new_policy_map);
......
// Copyright 2018 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/chromeos/policy/device_policy_cloud_external_data_manager.h"
#include <stdint.h>
#include <utility>
#include "base/location.h"
#include "base/sequenced_task_runner.h"
#include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h"
#include "components/policy/core/common/cloud/resource_cache.h"
namespace policy {
namespace {
const char kCacheKey[] = "device_policy_external_data";
// Maximum size of the device policy external data cache directory set to 10MB.
const int64_t kCacheMaxSize = 10 * 1024 * 1024;
// Only used for tests.
int64_t g_cache_max_size_override = 0;
} // namespace
DevicePolicyCloudExternalDataManager::DevicePolicyCloudExternalDataManager(
const GetChromePolicyDetailsCallback& get_policy_details,
scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
const base::FilePath& cache_path,
CloudPolicyStore* policy_store)
: CloudExternalDataManagerBase(get_policy_details, backend_task_runner) {
int cache_max_size = kCacheMaxSize;
if (g_cache_max_size_override != 0)
cache_max_size = g_cache_max_size_override;
resource_cache_ = std::make_unique<ResourceCache>(
cache_path, backend_task_runner, cache_max_size);
SetPolicyStore(policy_store);
SetExternalDataStore(std::make_unique<CloudExternalDataStore>(
kCacheKey, backend_task_runner, resource_cache_.get()));
}
DevicePolicyCloudExternalDataManager::~DevicePolicyCloudExternalDataManager() {
SetExternalDataStore(nullptr);
// Delete resource_cache_ on the background task runner to ensure that the
// delete is sequenced with the external data store's usage.
backend_task_runner_->DeleteSoon(FROM_HERE, std::move(resource_cache_));
}
void DevicePolicyCloudExternalDataManager::SetCacheMaxSizeForTesting(
int64_t cache_max_size) {
g_cache_max_size_override = cache_max_size;
}
} // namespace policy
// Copyright 2018 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.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_POLICY_CLOUD_EXTERNAL_DATA_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_POLICY_CLOUD_EXTERNAL_DATA_MANAGER_H_
#include <memory>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base.h"
#include "components/policy/core/common/policy_details.h"
namespace base {
class SequencedTaskRunner;
}
namespace policy {
class CloudPolicyStore;
class ResourceCache;
// Downloads, verifies and caches external data referenced by policies.
// This is the implementation for device policy external data.
class DevicePolicyCloudExternalDataManager
: public CloudExternalDataManagerBase {
public:
// |get_policy_details| is used to determine the maximum size that the
// data referenced by each policy can have. Download scheduling, verification,
// caching and retrieval tasks are done via the |backend_task_runner|, which
// must support file I/O. |resource_cache| is used to construct a data store
// which caches downloaded blobs on disk.
DevicePolicyCloudExternalDataManager(
const GetChromePolicyDetailsCallback& get_policy_details,
scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
const base::FilePath& cache_path,
CloudPolicyStore* policy_store);
~DevicePolicyCloudExternalDataManager() override;
// Sets the cache maximum size for testing.
// It's used to avoid creating big data in tests.
static void SetCacheMaxSizeForTesting(int64_t cache_max_size);
private:
// Cache used by the data store. Must outlive the data store.
std::unique_ptr<ResourceCache> resource_cache_;
DISALLOW_COPY_AND_ASSIGN(DevicePolicyCloudExternalDataManager);
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_POLICY_CLOUD_EXTERNAL_DATA_MANAGER_H_
// Copyright 2018 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 <memory>
#include <string>
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base.h"
#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
#include "chrome/browser/chromeos/policy/device_policy_builder.h"
#include "chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.h"
#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/chromeos_paths.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_service.h"
#include "components/policy/policy_constants.h"
#include "content/public/test/test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace policy {
namespace {
// The contents of these files are served as external data.
const char kExternalDataPath[] = "policy/printers_configuration.json";
const char kExternalDataPathUpdated[] =
"policy/printers_configuration_updated.json";
const char kExternalDataPathOverSizeLimit[] =
"policy/printers_configuration_over_size_limit.json";
// The name of an External Data Policy in Device Policy.
const char* const kPolicyName = policy::key::kDeviceNativePrinters;
const int64_t kTestCacheMaxSize = 64;
} // namespace
class DevicePolicyCloudExternalDataManagerTest
: public DevicePolicyCrosBrowserTest {
public:
DevicePolicyCloudExternalDataManagerTest() {
DevicePolicyCloudExternalDataManager::SetCacheMaxSizeForTesting(
kTestCacheMaxSize);
}
~DevicePolicyCloudExternalDataManagerTest() override = default;
protected:
void SetUpOnMainThread() override {
ASSERT_TRUE(embedded_test_server()->Start());
DevicePolicyCrosBrowserTest::SetUpOnMainThread();
BrowserPolicyConnectorChromeOS* policy_connector =
g_browser_process->platform_part()->browser_policy_connector_chromeos();
ASSERT_TRUE(policy_connector);
policy_service_ = policy_connector->GetPolicyService();
ASSERT_TRUE(
policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
policy_change_registrar_ = std::make_unique<PolicyChangeRegistrar>(
policy_service_, PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
policy_change_registrar_->Observe(
kPolicyName,
base::BindRepeating(
&DevicePolicyCloudExternalDataManagerTest::PolicyChangedCallback,
base::Unretained(this)));
policy_change_waiting_run_loop_ = std::make_unique<base::RunLoop>();
}
void TearDownOnMainThread() override {
policy_change_registrar_.reset();
DevicePolicyCrosBrowserTest::TearDownOnMainThread();
}
std::string GetExternalData() {
const PolicyMap& policies = policy_service_->GetPolicies(
PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
const PolicyMap::Entry* policy_entry = policies.Get(kPolicyName);
EXPECT_TRUE(policy_entry);
EXPECT_TRUE(policy_entry->external_data_fetcher);
base::RunLoop run_loop;
std::unique_ptr<std::string> fetched_external_data;
policy_entry->external_data_fetcher->Fetch(
base::BindRepeating(&test::ExternalDataFetchCallback,
&fetched_external_data, run_loop.QuitClosure()));
run_loop.Run();
EXPECT_TRUE(fetched_external_data);
return *fetched_external_data;
}
int64_t ComputeExternalDataCacheDirectorySize() {
base::FilePath device_policy_external_data_path;
CHECK(base::PathService::Get(chromeos::DIR_DEVICE_POLICY_EXTERNAL_DATA,
&device_policy_external_data_path));
base::ScopedAllowBlockingForTesting allow_blocking;
return base::ComputeDirectorySize(device_policy_external_data_path);
}
void SetDeviceNativePrintersExternalData(const std::string& policy) {
device_policy()
->payload()
.mutable_native_device_printers()
->set_external_policy(policy);
RefreshDevicePolicy();
WaitUntilPolicyChanged();
}
void ClearDeviceNativePrintersExternalData() {
device_policy()->payload().clear_native_device_printers();
RefreshDevicePolicy();
WaitUntilPolicyChanged();
}
std::string ReadExternalDataFile(const std::string& file_path) {
base::FilePath test_data_dir;
EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
std::string external_data;
{
base::ScopedAllowBlockingForTesting allow_blocking;
EXPECT_TRUE(base::ReadFileToString(test_data_dir.AppendASCII(file_path),
&external_data));
}
return external_data;
}
private:
void PolicyChangedCallback(const base::Value* old_value,
const base::Value* new_value) {
policy_change_waiting_run_loop_->Quit();
}
void WaitUntilPolicyChanged() {
policy_change_waiting_run_loop_->Run();
policy_change_waiting_run_loop_.reset(new base::RunLoop());
}
PolicyService* policy_service_ = nullptr;
std::unique_ptr<PolicyChangeRegistrar> policy_change_registrar_;
std::unique_ptr<base::RunLoop> policy_change_waiting_run_loop_;
};
IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,
FetchExternalData) {
SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
*embedded_test_server(), kExternalDataPath));
EXPECT_EQ(ReadExternalDataFile(kExternalDataPath), GetExternalData());
}
IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,
FetchOverSizeLimitExternalData) {
EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
std::string external_data =
ReadExternalDataFile(kExternalDataPathOverSizeLimit);
// Check that file size is greater than cache limit.
ASSERT_GT(base::checked_cast<int64_t>(external_data.size()),
kTestCacheMaxSize);
SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
*embedded_test_server(), kExternalDataPathOverSizeLimit));
EXPECT_EQ(external_data, GetExternalData());
// Check that nothing is cached because file was too big.
EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
}
IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest,
CleanUpResourceCache) {
EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
std::string external_data = ReadExternalDataFile(kExternalDataPath);
SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
*embedded_test_server(), kExternalDataPath));
EXPECT_EQ(external_data, GetExternalData());
EXPECT_EQ(base::checked_cast<int64_t>(external_data.size()),
ComputeExternalDataCacheDirectorySize());
external_data = ReadExternalDataFile(kExternalDataPathUpdated);
SetDeviceNativePrintersExternalData(test::ConstructExternalDataPolicy(
*embedded_test_server(), kExternalDataPathUpdated));
EXPECT_EQ(external_data, GetExternalData());
// Check that previous policy data was cleared and replaced by new one.
EXPECT_EQ(base::checked_cast<int64_t>(external_data.size()),
ComputeExternalDataCacheDirectorySize());
ClearDeviceNativePrintersExternalData();
// Check that policy data was cleared.
EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize());
}
} // namespace policy
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "chromeos/settings/cros_settings_names.h" #include "chromeos/settings/cros_settings_names.h"
#include "components/policy/core/common/chrome_schema.h" #include "components/policy/core/common/chrome_schema.h"
#include "components/policy/core/common/external_data_fetcher.h" #include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/external_data_manager.h"
#include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h" #include "components/policy/core/common/policy_types.h"
#include "components/policy/core/common/schema.h" #include "components/policy/core/common/schema.h"
...@@ -46,20 +47,41 @@ namespace { ...@@ -46,20 +47,41 @@ namespace {
// Otherwise, the policy will be set to a base::Value of the original // Otherwise, the policy will be set to a base::Value of the original
// |json_string|. This way, the faulty value can still be seen in // |json_string|. This way, the faulty value can still be seen in
// chrome://policy along with any errors/warnings. // chrome://policy along with any errors/warnings.
void SetJsonDevicePolicy(const std::string& policy_name, void SetJsonDevicePolicy(
const std::string& json_string, const std::string& policy_name,
PolicyMap* policies) { const std::string& json_string,
std::unique_ptr<ExternalDataFetcher> external_data_fetcher,
PolicyMap* policies) {
std::string error; std::string error;
std::unique_ptr<base::Value> decoded_json = std::unique_ptr<base::Value> decoded_json =
DecodeJsonStringAndNormalize(json_string, policy_name, &error); DecodeJsonStringAndNormalize(json_string, policy_name, &error);
auto value_to_set = decoded_json ? std::move(decoded_json) auto value_to_set = decoded_json ? std::move(decoded_json)
: std::make_unique<base::Value>(json_string); : std::make_unique<base::Value>(json_string);
policies->Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, policies->Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
POLICY_SOURCE_CLOUD, std::move(value_to_set), nullptr); POLICY_SOURCE_CLOUD, std::move(value_to_set),
std::move(external_data_fetcher));
if (!error.empty()) if (!error.empty())
policies->AddError(policy_name, error); policies->AddError(policy_name, error);
} }
void SetJsonDevicePolicy(const std::string& policy_name,
const std::string& json_string,
PolicyMap* policies) {
SetJsonDevicePolicy(policy_name, json_string,
/* external_data_fetcher */ nullptr, policies);
}
void SetExternalDataDevicePolicy(
const std::string& policy_name,
const std::string& json_string,
base::WeakPtr<ExternalDataManager> external_data_manager,
PolicyMap* policies) {
SetJsonDevicePolicy(
policy_name, json_string,
std::make_unique<ExternalDataFetcher>(external_data_manager, policy_name),
policies);
}
// Decodes a protobuf integer to an IntegerValue. Returns NULL in case the input // Decodes a protobuf integer to an IntegerValue. Returns NULL in case the input
// value is out of bounds. // value is out of bounds.
std::unique_ptr<base::Value> DecodeIntegerValue(google::protobuf::int64 value) { std::unique_ptr<base::Value> DecodeIntegerValue(google::protobuf::int64 value) {
...@@ -723,6 +745,22 @@ void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy, ...@@ -723,6 +745,22 @@ void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy,
} }
} }
void DecodeExternalDataPolicies(
const em::ChromeDeviceSettingsProto& policy,
base::WeakPtr<ExternalDataManager> external_data_manager,
PolicyMap* policies) {
// TODO(https://crbug.com/814364): Migrate device wallpaper here.
if (policy.has_native_device_printers()) {
const em::DeviceNativePrintersProto& container(
policy.native_device_printers());
if (container.has_external_policy()) {
SetExternalDataDevicePolicy(key::kDeviceNativePrinters,
container.external_policy(),
external_data_manager, policies);
}
}
}
void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy, void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
PolicyMap* policies) { PolicyMap* policies) {
if (policy.has_device_policy_refresh_rate()) { if (policy.has_device_policy_refresh_rate()) {
...@@ -932,15 +970,6 @@ void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy, ...@@ -932,15 +970,6 @@ void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
std::make_unique<base::Value>(container.name()), nullptr); std::make_unique<base::Value>(container.name()), nullptr);
} }
if (policy.has_native_device_printers()) {
const em::DeviceNativePrintersProto& container(
policy.native_device_printers());
if (container.has_external_policy()) {
SetJsonDevicePolicy(key::kDeviceNativePrinters,
container.external_policy(), policies);
}
}
if (policy.has_native_device_printers_access_mode()) { if (policy.has_native_device_printers_access_mode()) {
const em::DeviceNativePrintersAccessModeProto& container( const em::DeviceNativePrintersAccessModeProto& container(
policy.native_device_printers_access_mode()); policy.native_device_printers_access_mode());
...@@ -1136,14 +1165,17 @@ std::unique_ptr<base::Value> DecodeJsonStringAndNormalize( ...@@ -1136,14 +1165,17 @@ std::unique_ptr<base::Value> DecodeJsonStringAndNormalize(
return root; return root;
} }
void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy, void DecodeDevicePolicy(
PolicyMap* policies) { const em::ChromeDeviceSettingsProto& policy,
base::WeakPtr<ExternalDataManager> external_data_manager,
PolicyMap* policies) {
// Decode the various groups of policies. // Decode the various groups of policies.
DecodeLoginPolicies(policy, policies); DecodeLoginPolicies(policy, policies);
DecodeNetworkPolicies(policy, policies); DecodeNetworkPolicies(policy, policies);
DecodeReportingPolicies(policy, policies); DecodeReportingPolicies(policy, policies);
DecodeAutoUpdatePolicies(policy, policies); DecodeAutoUpdatePolicies(policy, policies);
DecodeAccessibilityPolicies(policy, policies); DecodeAccessibilityPolicies(policy, policies);
DecodeExternalDataPolicies(policy, external_data_manager, policies);
DecodeGenericPolicies(policy, policies); DecodeGenericPolicies(policy, policies);
} }
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "base/memory/weak_ptr.h"
namespace enterprise_management { namespace enterprise_management {
class ChromeDeviceSettingsProto; class ChromeDeviceSettingsProto;
} }
...@@ -18,6 +20,7 @@ class Value; ...@@ -18,6 +20,7 @@ class Value;
namespace policy { namespace policy {
class ExternalDataManager;
class PolicyMap; class PolicyMap;
// Decodes a JSON string to a base::Value and validates it against the schema // Decodes a JSON string to a base::Value and validates it against the schema
...@@ -35,6 +38,7 @@ std::unique_ptr<base::Value> DecodeJsonStringAndNormalize( ...@@ -35,6 +38,7 @@ std::unique_ptr<base::Value> DecodeJsonStringAndNormalize(
// PolicyMap. // PolicyMap.
void DecodeDevicePolicy( void DecodeDevicePolicy(
const enterprise_management::ChromeDeviceSettingsProto& policy, const enterprise_management::ChromeDeviceSettingsProto& policy,
base::WeakPtr<ExternalDataManager> external_data_manager,
PolicyMap* policies); PolicyMap* policies);
} // namespace policy } // namespace policy
......
...@@ -8,13 +8,18 @@ ...@@ -8,13 +8,18 @@
#include "base/callback.h" #include "base/callback.h"
#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
#include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h"
namespace policy { namespace policy {
FakeDeviceCloudPolicyManager::FakeDeviceCloudPolicyManager( FakeDeviceCloudPolicyManager::FakeDeviceCloudPolicyManager(
std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store, std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: DeviceCloudPolicyManagerChromeOS(std::move(store), task_runner, NULL), : DeviceCloudPolicyManagerChromeOS(
std::move(store),
std::make_unique<MockCloudExternalDataManager>(),
task_runner,
nullptr),
unregister_result_(true) {} unregister_result_(true) {}
FakeDeviceCloudPolicyManager::~FakeDeviceCloudPolicyManager() { FakeDeviceCloudPolicyManager::~FakeDeviceCloudPolicyManager() {
......
...@@ -1760,6 +1760,7 @@ test("browser_tests") { ...@@ -1760,6 +1760,7 @@ test("browser_tests") {
"../browser/chromeos/policy/component_active_directory_policy_browsertest.cc", "../browser/chromeos/policy/component_active_directory_policy_browsertest.cc",
"../browser/chromeos/policy/device_cloud_policy_browsertest.cc", "../browser/chromeos/policy/device_cloud_policy_browsertest.cc",
"../browser/chromeos/policy/device_local_account_browsertest.cc", "../browser/chromeos/policy/device_local_account_browsertest.cc",
"../browser/chromeos/policy/device_policy_cloud_external_data_manager_browsertest.cc",
"../browser/chromeos/policy/device_policy_cros_browser_test.cc", "../browser/chromeos/policy/device_policy_cros_browser_test.cc",
"../browser/chromeos/policy/device_policy_cros_browser_test.h", "../browser/chromeos/policy/device_policy_cros_browser_test.h",
"../browser/chromeos/policy/device_quirks_policy_browsertest.cc", "../browser/chromeos/policy/device_quirks_policy_browsertest.cc",
......
[{"display_name":"printer 1","uuid":"uuid1"}]
[{"display_name":"printer 1","uuid":"uuid1"},{"display_name":"printer 2","uuid":"uuid2"}]
[{"display_name":"printer 2","uuid":"uuid2"}]
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