Commit dff82fa9 authored by hamelphi's avatar hamelphi Committed by Commit bot

Allow whitelisted prefs to be displayed in ChromeOS in chrome://local-state.

BUG=506331

Review URL: https://codereview.chromium.org/1910323002

Cr-Commit-Position: refs/heads/master@{#389871}
parent b35b415c
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
#include "chrome/browser/ui/webui/local_state/local_state_ui.h" #include "chrome/browser/ui/webui/local_state/local_state_ui.h"
#include <string>
#include "base/json/json_string_value_serializer.h" #include "base/json/json_string_value_serializer.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -21,6 +21,15 @@ ...@@ -21,6 +21,15 @@
namespace { namespace {
// On ChromeOS, the local state file contains some information about other
// user accounts which we don't want to expose to other users. Use a whitelist
// to only show variations and UMA related fields which don't contain PII.
#if defined(OS_CHROMEOS)
#define ENABLE_FILTERING true
#else
#define ENABLE_FILTERING false
#endif // defined(OS_CHROMEOS)
// UI Handler for chrome://local-state. Displays the Local State file as JSON. // UI Handler for chrome://local-state. Displays the Local State file as JSON.
class LocalStateUIHandler : public content::WebUIMessageHandler { class LocalStateUIHandler : public content::WebUIMessageHandler {
public: public:
...@@ -51,10 +60,13 @@ void LocalStateUIHandler::RegisterMessages() { ...@@ -51,10 +60,13 @@ void LocalStateUIHandler::RegisterMessages() {
} }
void LocalStateUIHandler::HandleRequestJson(const base::ListValue* args) { void LocalStateUIHandler::HandleRequestJson(const base::ListValue* args) {
#if !defined(OS_CHROMEOS)
std::unique_ptr<base::DictionaryValue> local_state_values( std::unique_ptr<base::DictionaryValue> local_state_values(
g_browser_process->local_state()->GetPreferenceValuesOmitDefaults()); g_browser_process->local_state()->GetPreferenceValuesOmitDefaults());
if (ENABLE_FILTERING) {
std::vector<std::string> whitelisted_prefixes = {
"variations", "user_experience_metrics", "uninstall_metrics"};
internal::FilterPrefs(whitelisted_prefixes, local_state_values.get());
}
std::string json; std::string json;
JSONStringValueSerializer serializer(&json); JSONStringValueSerializer serializer(&json);
serializer.set_pretty_print(true); serializer.set_pretty_print(true);
...@@ -64,11 +76,39 @@ void LocalStateUIHandler::HandleRequestJson(const base::ListValue* args) { ...@@ -64,11 +76,39 @@ void LocalStateUIHandler::HandleRequestJson(const base::ListValue* args) {
web_ui()->CallJavascriptFunction("localState.setLocalState", web_ui()->CallJavascriptFunction("localState.setLocalState",
base::StringValue(json)); base::StringValue(json));
#endif // !defined(OS_CHROMEOS) }
// Returns true if |pref_name| starts with one of the |valid_prefixes|.
bool HasValidPrefix(const std::string& pref_name,
const std::vector<std::string> valid_prefixes) {
for (const std::string& prefix : valid_prefixes) {
if (base::StartsWith(pref_name, prefix, base::CompareCase::SENSITIVE))
return true;
}
return false;
} }
} // namespace } // namespace
namespace internal {
void FilterPrefs(const std::vector<std::string>& valid_prefixes,
base::DictionaryValue* prefs) {
std::vector<std::string> prefs_to_remove;
for (base::DictionaryValue::Iterator it(*prefs); !it.IsAtEnd();
it.Advance()) {
if (!HasValidPrefix(it.key(), valid_prefixes))
prefs_to_remove.push_back(it.key());
}
for (const std::string& pref_to_remove : prefs_to_remove) {
std::unique_ptr<base::Value> removed_value;
bool successfully_removed = prefs->Remove(pref_to_remove, &removed_value);
DCHECK(successfully_removed);
}
}
} // namespace internal
LocalStateUI::LocalStateUI(content::WebUI* web_ui) : WebUIController(web_ui) { LocalStateUI::LocalStateUI(content::WebUI* web_ui) : WebUIController(web_ui) {
// Set up the chrome://local-state source. // Set up the chrome://local-state source.
content::WebUIDataSource* html_source = content::WebUIDataSource* html_source =
......
...@@ -5,9 +5,26 @@ ...@@ -5,9 +5,26 @@
#ifndef CHROME_BROWSER_UI_WEBUI_LOCAL_STATE_LOCAL_STATE_UI_H_ #ifndef CHROME_BROWSER_UI_WEBUI_LOCAL_STATE_LOCAL_STATE_UI_H_
#define CHROME_BROWSER_UI_WEBUI_LOCAL_STATE_LOCAL_STATE_UI_H_ #define CHROME_BROWSER_UI_WEBUI_LOCAL_STATE_LOCAL_STATE_UI_H_
#include <string>
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_controller.h"
namespace base {
class DictionaryValue;
}
// Namespace for exposing the method for unit tests.
namespace internal {
// Removes elements from |prefs| where the key does not match any of the
// prefixes in |valid_prefixes|.
void FilterPrefs(const std::vector<std::string>& valid_prefixes,
base::DictionaryValue* prefs);
} // namespace internal
// Controller for chrome://local-state/ page. // Controller for chrome://local-state/ page.
class LocalStateUI : public content::WebUIController { class LocalStateUI : public content::WebUIController {
public: public:
......
// Copyright 2016 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/ui/webui/local_state/local_state_ui.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(LocalStateUiTest, FilterPrefs) {
std::vector<std::string> prefixes = {"foo", "bar", "baz"};
std::vector<std::string> invalid_pref_keys = {"fo", "ar", "afoo"};
std::vector<std::string> valid_pref_keys = {"foo", "foom", "bar.stuff"};
std::vector<std::string> all_pref_keys = invalid_pref_keys;
all_pref_keys.insert(all_pref_keys.end(), valid_pref_keys.begin(),
valid_pref_keys.end());
base::DictionaryValue prefs;
for (const std::string& key : all_pref_keys) {
prefs.Set(key, new base::StringValue(key + "_value"));
}
internal::FilterPrefs(prefixes, &prefs);
for (const std::string& invalid_key : invalid_pref_keys) {
std::string value;
EXPECT_FALSE(prefs.GetString(invalid_key, &value));
}
for (const std::string& valid_key : valid_pref_keys) {
std::string value;
EXPECT_TRUE(prefs.GetString(valid_key, &value));
EXPECT_EQ(valid_key + "_value", value);
}
}
...@@ -281,6 +281,7 @@ ...@@ -281,6 +281,7 @@
'browser/ui/website_settings/website_settings_unittest.cc', 'browser/ui/website_settings/website_settings_unittest.cc',
'browser/ui/webui/browsing_history_handler_unittest.cc', 'browser/ui/webui/browsing_history_handler_unittest.cc',
'browser/ui/webui/fileicon_source_unittest.cc', 'browser/ui/webui/fileicon_source_unittest.cc',
'browser/ui/webui/local_state/local_state_ui_unittest.cc',
'browser/ui/webui/log_web_ui_url_unittest.cc', 'browser/ui/webui/log_web_ui_url_unittest.cc',
'browser/update_client/chrome_update_query_params_delegate_unittest.cc', 'browser/update_client/chrome_update_query_params_delegate_unittest.cc',
'common/chrome_content_client_unittest.cc', 'common/chrome_content_client_unittest.cc',
......
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