Add a path parsing policy handler for the RoamingProfileLocation policy.
This policy should like most other FilePath policies parse variables
in its content before storing its value in its backing pref.
BUG=726007
TEST=unit_tests
Review-Url: https://codereview.chromium.org/2912353003
Cr-Commit-Position: refs/heads/master@{#476272}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 44bd37a..f5c2bb7 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3520,6 +3520,8 @@
"obsolete_system/obsolete_system_win.cc",
"pdf/pdf_extension_util.cc",
"pdf/pdf_extension_util.h",
+ "policy/local_sync_policy_handler.cc",
+ "policy/local_sync_policy_handler.h",
"process_singleton_modal_dialog_lock.cc",
"process_singleton_modal_dialog_lock.h",
"process_singleton_posix.cc",
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 4981e0b..9bebc11 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -78,6 +78,7 @@
#if !defined(OS_ANDROID)
#include "chrome/browser/download/download_dir_policy_handler.h"
+#include "chrome/browser/policy/local_sync_policy_handler.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -669,9 +670,6 @@
{ key::kRoamingProfileSupportEnabled,
syncer::prefs::kEnableLocalSyncBackend,
base::Value::Type::BOOLEAN },
- { key::kRoamingProfileLocation,
- syncer::prefs::kLocalSyncBackendDir,
- base::Value::Type::STRING },
{ key::kNetworkTimeQueriesEnabled,
network_time::prefs::kNetworkTimeQueriesEnabled,
@@ -922,6 +920,7 @@
#if !defined(OS_ANDROID)
handlers->AddHandler(base::WrapUnique(new DownloadDirPolicyHandler));
+ handlers->AddHandler(base::MakeUnique<LocalSyncPolicyHandler>());
handlers->AddHandler(base::MakeUnique<SimpleSchemaValidatingPolicyHandler>(
key::kRegisteredProtocolHandlers,
diff --git a/chrome/browser/policy/local_sync_policy_handler.cc b/chrome/browser/policy/local_sync_policy_handler.cc
new file mode 100644
index 0000000..88758efee
--- /dev/null
+++ b/chrome/browser/policy/local_sync_policy_handler.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 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/policy/local_sync_policy_handler.h"
+
+#include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
+#include "base/values.h"
+#include "chrome/browser/policy/policy_path_parser.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/policy_constants.h"
+#include "components/prefs/pref_value_map.h"
+#include "components/sync/base/pref_names.h"
+
+namespace policy {
+
+LocalSyncPolicyHandler::LocalSyncPolicyHandler()
+ : TypeCheckingPolicyHandler(key::kRoamingProfileLocation,
+ base::Value::Type::STRING) {}
+
+LocalSyncPolicyHandler::~LocalSyncPolicyHandler() {}
+
+void LocalSyncPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
+ PrefValueMap* prefs) {
+ const base::Value* value = policies.GetValue(policy_name());
+ base::FilePath::StringType string_value;
+ if (value && value->GetAsString(&string_value)) {
+ base::FilePath::StringType expanded_value =
+ policy::path_parser::ExpandPathVariables(string_value);
+ prefs->SetValue(syncer::prefs::kLocalSyncBackendDir,
+ base::MakeUnique<base::Value>(expanded_value));
+ }
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/local_sync_policy_handler.h b/chrome/browser/policy/local_sync_policy_handler.h
new file mode 100644
index 0000000..99e9802
--- /dev/null
+++ b/chrome/browser/policy/local_sync_policy_handler.h
@@ -0,0 +1,30 @@
+// Copyright 2017 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_POLICY_LOCAL_SYNC_POLICY_HANDLER_H_
+#define CHROME_BROWSER_POLICY_LOCAL_SYNC_POLICY_HANDLER_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/policy/core/browser/configuration_policy_handler.h"
+
+namespace policy {
+
+// ConfigurationPolicyHandler for the RoamingProfileLocation policy.
+class LocalSyncPolicyHandler : public TypeCheckingPolicyHandler {
+ public:
+ LocalSyncPolicyHandler();
+ ~LocalSyncPolicyHandler() override;
+
+ // ConfigurationPolicyHandler methods:
+ void ApplyPolicySettings(const PolicyMap& policies,
+ PrefValueMap* prefs) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LocalSyncPolicyHandler);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_LOCAL_SYNC_POLICY_HANDLER_H_
diff --git a/chrome/browser/policy/local_sync_policy_handler_unittest.cc b/chrome/browser/policy/local_sync_policy_handler_unittest.cc
new file mode 100644
index 0000000..075c586
--- /dev/null
+++ b/chrome/browser/policy/local_sync_policy_handler_unittest.cc
@@ -0,0 +1,56 @@
+// Copyright 2017 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 <string>
+
+#include "base/memory/ptr_util.h"
+#include "base/values.h"
+#include "chrome/browser/policy/local_sync_policy_handler.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/core/common/policy_types.h"
+#include "components/policy/policy_constants.h"
+#include "components/prefs/pref_value_map.h"
+#include "components/sync/base/pref_names.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+class LocalSyncPolicyTest : public testing::Test {
+ protected:
+ PolicyMap policy_;
+ LocalSyncPolicyHandler handler_;
+ PrefValueMap prefs_;
+};
+
+TEST_F(LocalSyncPolicyTest, Default) {
+ handler_.ApplyPolicySettings(policy_, &prefs_);
+ EXPECT_FALSE(prefs_.GetValue(syncer::prefs::kLocalSyncBackendDir, nullptr));
+}
+
+// RoamingProfileLocation policy expects a string; give it a boolean.
+TEST_F(LocalSyncPolicyTest, SetPolicyInvalid) {
+ policy_.Set(key::kRoamingProfileLocation, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
+ base::MakeUnique<base::Value>(false), nullptr);
+ handler_.ApplyPolicySettings(policy_, &prefs_);
+ EXPECT_FALSE(prefs_.GetValue(syncer::prefs::kLocalSyncBackendDir, nullptr));
+}
+
+// Use a variable in the value. It should be expanded by the handler.
+TEST_F(LocalSyncPolicyTest, SetPolicyValid) {
+ const std::string in = "${user_name}/foo";
+ policy_.Set(key::kRoamingProfileLocation, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
+ base::MakeUnique<base::Value>(in), nullptr);
+ handler_.ApplyPolicySettings(policy_, &prefs_);
+
+ const base::Value* value;
+ ASSERT_TRUE(prefs_.GetValue(syncer::prefs::kLocalSyncBackendDir, &value));
+ std::string out;
+ ASSERT_TRUE(value->GetAsString(&out));
+ EXPECT_NE(std::string::npos, out.find("foo"));
+ EXPECT_EQ(std::string::npos, out.find("${user_name}"));
+}
+
+} // namespace policy
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 8fa665c0..39fd326 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3724,6 +3724,7 @@
"../browser/media/router/mojo/media_route_controller_unittest.cc",
"../browser/media/router/mojo/media_router_mojo_impl_unittest.cc",
"../browser/media/router/mojo/media_router_mojo_metrics_unittest.cc",
+ "../browser/policy/local_sync_policy_handler_unittest.cc",
"../browser/renderer_context_menu/render_view_context_menu_test_util.cc",
"../browser/renderer_context_menu/render_view_context_menu_test_util.h",
"../browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc",