Commit b0823d3c authored by Maksim Moskvitin's avatar Maksim Moskvitin Committed by Commit Bot

[Sync:USS] Implement NigoriStorageImpl

We write NigoriLocalData in encrypted form to corresponding file using
ImportantFileWriter. Reading is just mirrored version of writing.

Bug: 922900
Change-Id: I299f55450e74edac29beaacf7b5dc659f5fd8f8a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1768424
Commit-Queue: Maksim Moskvitin <mmoskvitin@google.com>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#690014}
parent 004070c0
......@@ -643,6 +643,7 @@ source_set("unit_tests") {
"nigori/cryptographer_unittest.cc",
"nigori/nigori_key_bag_unittest.cc",
"nigori/nigori_model_type_processor_unittest.cc",
"nigori/nigori_storage_impl_unittest.cc",
"nigori/nigori_sync_bridge_impl_unittest.cc",
"nigori/nigori_unittest.cc",
"protocol/proto_enum_conversions_unittest.cc",
......
......@@ -6,11 +6,16 @@
#include <string>
#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
#include "components/sync/base/encryptor.h"
namespace syncer {
NigoriStorageImpl::NigoriStorageImpl(const base::FilePath& path,
const Encryptor* encryptor) {
NOTIMPLEMENTED();
const Encryptor* encryptor)
: path_(path), encryptor_(encryptor) {
DCHECK(encryptor_);
}
NigoriStorageImpl::~NigoriStorageImpl() {
......@@ -19,13 +24,48 @@ NigoriStorageImpl::~NigoriStorageImpl() {
void NigoriStorageImpl::StoreData(const sync_pb::NigoriLocalData& data) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
NOTIMPLEMENTED();
std::string serialized_data = data.SerializeAsString();
if (serialized_data.empty()) {
DLOG(ERROR) << "Failed to serialize NigoriLocalData.";
return;
}
std::string encrypted_data;
if (!encryptor_->EncryptString(serialized_data, &encrypted_data)) {
DLOG(ERROR) << "Failed to encrypt NigoriLocalData.";
return;
}
if (!base::ImportantFileWriter::WriteFileAtomically(path_, encrypted_data)) {
DLOG(ERROR) << "Failed to write NigoriLocalData into file.";
}
}
base::Optional<sync_pb::NigoriLocalData> NigoriStorageImpl::RestoreData() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
NOTIMPLEMENTED();
return base::nullopt;
if (!base::PathExists(path_)) {
return base::nullopt;
}
std::string encrypted_data;
if (!base::ReadFileToString(path_, &encrypted_data)) {
DLOG(ERROR) << "Failed to read NigoriLocalData from file.";
return base::nullopt;
}
std::string serialized_data;
if (!encryptor_->DecryptString(encrypted_data, &serialized_data)) {
DLOG(ERROR) << "Failed to decrypt NigoriLocalData.";
return base::nullopt;
}
sync_pb::NigoriLocalData data;
if (!data.ParseFromString(serialized_data)) {
DLOG(ERROR) << "Failed to parse NigoriLocalData.";
return base::nullopt;
}
return data;
}
} // namespace syncer
......@@ -15,6 +15,7 @@ class Encryptor;
class NigoriStorageImpl : NigoriStorage {
public:
// |encryptor| must be not null and must outlive this object.
NigoriStorageImpl(const base::FilePath& path, const Encryptor* encryptor);
~NigoriStorageImpl() override;
......@@ -24,6 +25,9 @@ class NigoriStorageImpl : NigoriStorage {
base::Optional<sync_pb::NigoriLocalData> RestoreData() override;
private:
base::FilePath path_;
const Encryptor* const encryptor_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(NigoriStorageImpl);
};
......
// 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 "components/sync/nigori/nigori_storage_impl.h"
#include "base/files/scoped_temp_dir.h"
#include "components/sync/base/fake_encryptor.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
namespace {
sync_pb::NigoriLocalData MakeSomeNigoriLocalData() {
sync_pb::NigoriLocalData result;
result.mutable_model_type_state()->set_initial_sync_done(true);
result.mutable_entity_metadata()->set_sequence_number(1);
result.mutable_nigori_model()->set_encrypt_everything(true);
return result;
}
class NigoriStorageImplTest : public testing::Test {
protected:
NigoriStorageImplTest() = default;
~NigoriStorageImplTest() override = default;
void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
const Encryptor* encryptor() { return &encryptor_; }
base::FilePath GetFilePath() {
return temp_dir_.GetPath().Append(
base::FilePath(FILE_PATH_LITERAL("some_file")));
}
private:
FakeEncryptor encryptor_;
base::ScopedTempDir temp_dir_;
};
TEST_F(NigoriStorageImplTest, ShouldBeAbleToRestoreAfterWrite) {
NigoriStorageImpl writer_storage(GetFilePath(), encryptor());
sync_pb::NigoriLocalData write_data = MakeSomeNigoriLocalData();
writer_storage.StoreData(write_data);
// Use different NigoriStorageImpl when reading to avoid dependency on its
// state and emulate browser restart.
NigoriStorageImpl reader_storage(GetFilePath(), encryptor());
base::Optional<sync_pb::NigoriLocalData> read_data =
reader_storage.RestoreData();
EXPECT_NE(read_data, base::nullopt);
EXPECT_EQ(read_data->SerializeAsString(), write_data.SerializeAsString());
}
TEST_F(NigoriStorageImplTest, ShouldReturnNulloptWhenFileNotExists) {
NigoriStorageImpl storage(GetFilePath(), encryptor());
EXPECT_EQ(storage.RestoreData(), base::nullopt);
}
} // namespace
} // namespace syncer
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