Commit bcf3b929 authored by Himanshu Jaju's avatar Himanshu Jaju Committed by Commit Bot

[Sharing] Add SharingSyncPreference implementation.

Bug: 966030
Change-Id: Id6f24392364a376c9234d68ecc154e131a95002f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1626592
Commit-Queue: Himanshu Jaju <himanshujaju@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Auto-Submit: Himanshu Jaju <himanshujaju@chromium.org>
Cr-Commit-Position: refs/heads/master@{#667089}
parent 8f2058ee
......@@ -1510,6 +1510,8 @@ jumbo_split_static_library("browser") {
"sharing/sharing_service.h",
"sharing/sharing_service_factory.cc",
"sharing/sharing_service_factory.h",
"sharing/sharing_sync_preference.cc",
"sharing/sharing_sync_preference.h",
"shell_integration.cc",
"shell_integration.h",
"shell_integration_android.cc",
......
......@@ -62,6 +62,7 @@
#include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h"
#include "chrome/browser/search/local_ntp_first_run_field_trial_handler.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/sharing/sharing_sync_preference.h"
#include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
#include "chrome/browser/ssl/ssl_config_service_manager.h"
#include "chrome/browser/task_manager/task_manager_interface.h"
......@@ -723,6 +724,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
safe_browsing::RegisterProfilePrefs(registry);
SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs(registry);
SessionStartupPref::RegisterProfilePrefs(registry);
SharingSyncPreference::RegisterProfilePrefs(registry);
sync_sessions::SessionSyncPrefs::RegisterProfilePrefs(registry);
syncer::SyncPrefs::RegisterProfilePrefs(registry);
syncer::PerUserTopicRegistrationManager::RegisterProfilePrefs(registry);
......
// Copyright 2019 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/sharing/sharing_sync_preference.h"
#include "base/base64.h"
#include "base/value_conversions.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/sync_preferences/pref_service_syncable.h"
namespace {
const char kVapidKey[] = "sharing.vapid_key";
const char kVapidECPrivateKey[] = "vapid_private_key";
const char kVapidCreationTimestamp[] = "vapid_creation_timestamp";
const char kSyncedDevices[] = "sharing.synced_devices";
const char kDeviceFcmToken[] = "device_fcm_token";
const char kDeviceP256dh[] = "device_p256dh";
const char kDeviceAuthSecret[] = "device_auth_secret";
const char kDeviceCapabilities[] = "device_capabilities";
} // namespace
SharingSyncPreference::Device::Device(const std::string& fcm_token,
const std::string& p256dh,
const std::string& auth_secret,
const int capabilities)
: fcm_token(fcm_token),
p256dh(p256dh),
auth_secret(auth_secret),
capabilities(capabilities) {}
SharingSyncPreference::Device::Device(Device&& other) = default;
SharingSyncPreference::Device::~Device() = default;
SharingSyncPreference::SharingSyncPreference(PrefService* prefs)
: prefs_(prefs) {}
SharingSyncPreference::~SharingSyncPreference() = default;
// static
void SharingSyncPreference::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterDictionaryPref(
kSyncedDevices, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterDictionaryPref(
kVapidKey, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
}
base::Optional<std::vector<uint8_t>> SharingSyncPreference::GetVapidKey()
const {
const base::DictionaryValue* vapid_key = prefs_->GetDictionary(kVapidKey);
std::string base64_private_key, private_key;
if (!vapid_key->GetString(kVapidECPrivateKey, &base64_private_key))
return base::nullopt;
if (base::Base64Decode(base64_private_key, &private_key)) {
return std::vector<uint8_t>(private_key.begin(), private_key.end());
} else {
LOG(ERROR) << "Could not decode stored vapid keys.";
return base::nullopt;
}
}
void SharingSyncPreference::SetVapidKey(
const std::vector<uint8_t>& vapid_key) const {
base::Time creation_timestamp = base::Time::Now();
std::string base64_vapid_key;
base::Base64Encode(std::string(vapid_key.begin(), vapid_key.end()),
&base64_vapid_key);
DictionaryPrefUpdate update(prefs_, kVapidKey);
update->SetString(kVapidECPrivateKey, base64_vapid_key);
update->SetString(kVapidCreationTimestamp,
base::CreateTimeValue(creation_timestamp).GetString());
}
std::map<std::string, SharingSyncPreference::Device>
SharingSyncPreference::GetSyncedDevices() const {
std::map<std::string, Device> synced_devices;
const base::DictionaryValue* devices_preferences =
prefs_->GetDictionary(kSyncedDevices);
for (const auto& it : devices_preferences->DictItems()) {
base::Optional<Device> device = ValueToDevice(it.second);
if (device)
synced_devices.emplace(it.first, std::move(*device));
}
return synced_devices;
}
void SharingSyncPreference::SetSyncDevice(const std::string& guid,
const Device& device) {
DictionaryPrefUpdate update(prefs_, kSyncedDevices);
update->SetKey(guid, DeviceToValue(device));
}
void SharingSyncPreference::RemoveDevice(const std::string& guid) {
DictionaryPrefUpdate update(prefs_, kSyncedDevices);
update->RemoveKey(guid);
}
base::Value SharingSyncPreference::DeviceToValue(const Device& device) const {
std::string base64_p256dh, base64_auth_secret;
base::Base64Encode(device.p256dh, &base64_p256dh);
base::Base64Encode(device.auth_secret, &base64_auth_secret);
base::Value result(base::Value::Type::DICTIONARY);
result.SetStringKey(kDeviceFcmToken, device.fcm_token);
result.SetStringKey(kDeviceP256dh, base64_p256dh);
result.SetStringKey(kDeviceAuthSecret, base64_auth_secret);
result.SetIntKey(kDeviceCapabilities, device.capabilities);
return result;
}
base::Optional<SharingSyncPreference::Device>
SharingSyncPreference::ValueToDevice(const base::Value& value) const {
const std::string* fcm_token = value.FindStringKey(kDeviceFcmToken);
const std::string* base64_p256dh = value.FindStringKey(kDeviceP256dh);
const std::string* base64_auth_secret =
value.FindStringKey(kDeviceAuthSecret);
const base::Optional<int> capabilities =
value.FindIntKey(kDeviceCapabilities);
std::string p256dh, auth_secret;
if (!fcm_token || !base64_p256dh || !base64_auth_secret || !capabilities ||
!base::Base64Decode(*base64_p256dh, &p256dh) ||
!base::Base64Decode(*base64_auth_secret, &auth_secret)) {
LOG(ERROR) << "Could not convert synced value to device object.";
return base::nullopt;
} else {
return Device(*fcm_token, p256dh, auth_secret, *capabilities);
}
}
// Copyright 2019 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_SHARING_SHARING_SYNC_PREFERENCE_H_
#define CHROME_BROWSER_SHARING_SHARING_SYNC_PREFERENCE_H_
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "base/values.h"
namespace user_prefs {
class PrefRegistrySyncable;
}
class PrefService;
// SharingSyncPreference manages all preferences related to Sharing using Sync,
// such as storing list of user devices synced via Chrome and VapidKey used
// for authentication.
class SharingSyncPreference {
public:
struct Device {
Device(const std::string& fcm_token,
const std::string& p256dh,
const std::string& auth_secret,
const int capabilities);
Device(Device&& other);
~Device();
// FCM registration token of device for sending SharingMessage.
std::string fcm_token;
// Subscription public key required for WebPush protocol.
std::string p256dh;
// Auth secret key required for WebPush protocol.
std::string auth_secret;
// Bitmask of capabilities, defined in SharingDeviceCapability enum, that
// are supported by the device.
int capabilities;
};
explicit SharingSyncPreference(PrefService* prefs);
~SharingSyncPreference();
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Returns VAPID key from preferences if present, otherwise returns
// base::nullopt.
// For more information on vapid keys, please see
// https://tools.ietf.org/html/draft-thomson-webpush-vapid-02
base::Optional<std::vector<uint8_t>> GetVapidKey() const;
// Adds VAPID key to preferences for syncing across devices.
void SetVapidKey(const std::vector<uint8_t>& vapid_key) const;
// Returns the map of guid to device from sharing preferences. Guid is same
// as sync device guid.
std::map<std::string, Device> GetSyncedDevices() const;
// Stores |device| with key |guid| in sharing preferences.
// |guid| is same as sync device guid.
void SetSyncDevice(const std::string& guid, const Device& device);
// Removes device corresponding to |guid| from sharing preferences.
// |guid| is same as sync device guid.
void RemoveDevice(const std::string& guid);
private:
base::Value DeviceToValue(const Device& device) const;
base::Optional<Device> ValueToDevice(const base::Value& value) const;
PrefService* prefs_;
DISALLOW_COPY_AND_ASSIGN(SharingSyncPreference);
};
#endif // CHROME_BROWSER_SHARING_SHARING_SYNC_PREFERENCE_H_
// Copyright 2019 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/sharing/sharing_sync_preference.h"
#include <memory>
#include "components/prefs/scoped_user_pref_update.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kVapidKeyStr[] = "test_vapid_key";
const std::vector<uint8_t> kVapidKey =
std::vector<uint8_t>(std::begin(kVapidKeyStr), std::end(kVapidKeyStr));
const char kDeviceGuid[] = "test_device";
const char kDeviceFcmToken[] = "test_fcm_token";
const char kDeviceAuthToken[] = "test_auth_token";
const char kDeviceP256dh[] = "test_p256dh";
const int kCapabilities = 1;
class SharingSyncPreferenceTest : public testing::Test {
protected:
SharingSyncPreferenceTest() : sharing_sync_preference_(&prefs_) {
SharingSyncPreference::RegisterProfilePrefs(prefs_.registry());
}
void SyncDefaultDevice() {
sharing_sync_preference_.SetSyncDevice(
kDeviceGuid,
SharingSyncPreference::Device(kDeviceFcmToken, kDeviceP256dh,
kDeviceAuthToken, kCapabilities));
}
base::Optional<SharingSyncPreference::Device> GetDevice(
const std::string& guid) {
std::map<std::string, SharingSyncPreference::Device> synced_devices =
sharing_sync_preference_.GetSyncedDevices();
auto it = synced_devices.find(guid);
if (it == synced_devices.end())
return base::nullopt;
else
return std::move(it->second);
}
sync_preferences::TestingPrefServiceSyncable prefs_;
SharingSyncPreference sharing_sync_preference_;
};
} // namespace
TEST_F(SharingSyncPreferenceTest, UpdateVapidKeys) {
EXPECT_EQ(base::nullopt, sharing_sync_preference_.GetVapidKey());
sharing_sync_preference_.SetVapidKey(kVapidKey);
EXPECT_EQ(kVapidKey, sharing_sync_preference_.GetVapidKey());
}
TEST_F(SharingSyncPreferenceTest, RemoveDevice) {
SyncDefaultDevice();
EXPECT_NE(base::nullopt, GetDevice(kDeviceGuid));
sharing_sync_preference_.RemoveDevice(kDeviceGuid);
EXPECT_EQ(base::nullopt, GetDevice(kDeviceGuid));
}
TEST_F(SharingSyncPreferenceTest, SyncDevice) {
EXPECT_EQ(base::nullopt, GetDevice(kDeviceGuid));
SyncDefaultDevice();
base::Optional<SharingSyncPreference::Device> device = GetDevice(kDeviceGuid);
EXPECT_NE(base::nullopt, device);
EXPECT_EQ(kDeviceFcmToken, device->fcm_token);
EXPECT_EQ(kDeviceP256dh, device->p256dh);
EXPECT_EQ(kDeviceAuthToken, device->auth_secret);
EXPECT_EQ(kCapabilities, device->capabilities);
}
......@@ -3051,6 +3051,7 @@ test("unit_tests") {
"../browser/sessions/chrome_serialized_navigation_driver_unittest.cc",
"../browser/sessions/restore_on_startup_policy_handler_unittest.cc",
"../browser/sessions/session_common_utils_unittest.cc",
"../browser/sharing/sharing_sync_preference_unittest.cc",
"../browser/shell_integration_win_unittest.cc",
"../browser/signin/account_consistency_mode_manager_unittest.cc",
"../browser/signin/chrome_device_id_helper_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