Commit 9e453cfc authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS MultiDevice] Add LocalDeviceMetadataManager.

This class provides an interface for setting and retrieving metadata
about the local device (i.e., the device on which this code is running).

The "default" metadata should be set once the user logs in and should be
used for all requests during a user session. Before the user signs in,
however, the default metadata is unset, since metadata is account-
specific. Thus, this class also provides the ability to tie arbitrary
metadata to a specific request ID.

Bug: 824568, 752273
Change-Id: I78e3da20ff680c1c4cc9ce70e203005aacbdfe23
Reviewed-on: https://chromium-review.googlesource.com/1079722
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarRyan Hansberry <hansberry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563483}
parent 7cd811f1
...@@ -34,6 +34,8 @@ static_library("secure_channel") { ...@@ -34,6 +34,8 @@ static_library("secure_channel") {
"connection_medium.h", "connection_medium.h",
"connection_role.cc", "connection_role.cc",
"connection_role.h", "connection_role.h",
"local_device_metadata_manager.cc",
"local_device_metadata_manager.h",
"multiplexed_channel.cc", "multiplexed_channel.cc",
"multiplexed_channel.h", "multiplexed_channel.h",
"multiplexed_channel_impl.cc", "multiplexed_channel_impl.cc",
...@@ -118,6 +120,7 @@ source_set("unit_tests") { ...@@ -118,6 +120,7 @@ source_set("unit_tests") {
"connect_to_device_operation_base_unittest.cc", "connect_to_device_operation_base_unittest.cc",
"connect_to_device_operation_factory_base_unittest.cc", "connect_to_device_operation_factory_base_unittest.cc",
"connection_attempt_base_unittest.cc", "connection_attempt_base_unittest.cc",
"local_device_metadata_manager_unittest.cc",
"multiplexed_channel_impl_unittest.cc", "multiplexed_channel_impl_unittest.cc",
"pending_ble_initiator_connection_request_unittest.cc", "pending_ble_initiator_connection_request_unittest.cc",
"pending_ble_listener_connection_request_unittest.cc", "pending_ble_listener_connection_request_unittest.cc",
......
// 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 "chromeos/services/secure_channel/local_device_metadata_manager.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
namespace chromeos {
namespace secure_channel {
LocalDeviceMetadataManager::LocalDeviceMetadataManager() = default;
LocalDeviceMetadataManager::~LocalDeviceMetadataManager() = default;
void LocalDeviceMetadataManager::SetDefaultLocalDeviceDataMetadata(
cryptauth::RemoteDeviceRef default_local_device_metadata) {
if (default_local_device_metadata_) {
PA_LOG(WARNING) << "LocalDeviceMetadataManager::"
<< "SetDefaultLocalDeviceDataMetadata(): Setting the "
<< "default local device metadata, but one was already "
<< "set. Overwriting the old one.";
}
default_local_device_metadata_ = default_local_device_metadata;
}
const base::Optional<cryptauth::RemoteDeviceRef>&
LocalDeviceMetadataManager::GetDefaultLocalDeviceMetadata() const {
return default_local_device_metadata_;
}
void LocalDeviceMetadataManager::SetLocalDeviceMetadataForRequest(
const base::UnguessableToken& request_id,
cryptauth::RemoteDeviceRef local_device_metadata) {
if (base::ContainsKey(request_id_to_metadata_map_, request_id)) {
PA_LOG(ERROR) << "LocalDeviceMetadataManager::"
<< "SetLocalDeviceMetadataForRequest(): Setting local device "
<< "metadata for request ID " << request_id << ", but that "
<< "request already had metadata set.";
NOTREACHED();
}
request_id_to_metadata_map_.insert(
std::make_pair(request_id, local_device_metadata));
}
base::Optional<cryptauth::RemoteDeviceRef>
LocalDeviceMetadataManager::GetLocalDeviceMetadataForRequest(
const base::UnguessableToken& request_id) const {
if (base::ContainsKey(request_id_to_metadata_map_, request_id))
return request_id_to_metadata_map_.at(request_id);
return base::nullopt;
}
} // namespace secure_channel
} // namespace chromeos
// 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 CHROMEOS_SERVICES_SECURE_CHANNEL_LOCAL_DEVICE_METADATA_MANAGER_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_LOCAL_DEVICE_METADATA_MANAGER_H_
#include <unordered_map>
#include "base/macros.h"
#include "base/optional.h"
#include "base/unguessable_token.h"
#include "components/cryptauth/remote_device_ref.h"
namespace chromeos {
namespace secure_channel {
// Provides the ability set/fetch data associated with the local device.
class LocalDeviceMetadataManager {
public:
LocalDeviceMetadataManager();
virtual ~LocalDeviceMetadataManager();
// Sets the default local device metadata; this function is intended to be
// called when the user logs in.
void SetDefaultLocalDeviceDataMetadata(
cryptauth::RemoteDeviceRef default_local_device_metadata);
// Return value is base::nullopt if SetDefaultLocalDeviceDataMetadata() has
// not yet been called.
const base::Optional<cryptauth::RemoteDeviceRef>&
GetDefaultLocalDeviceMetadata() const;
// Sets the local device metadata for the request with id |request_id|. This
// function is intended to be used before the user logs in; before log-in,
// the local device can be represented by several RemoteDeviceRef objects,
// each specific to a different user's account.
void SetLocalDeviceMetadataForRequest(
const base::UnguessableToken& request_id,
cryptauth::RemoteDeviceRef default_local_device_metadata);
// Return value is base::nullopt if SetLocalDeviceMetadataForRequest() has
// not yet been called for the |request_id|.
base::Optional<cryptauth::RemoteDeviceRef> GetLocalDeviceMetadataForRequest(
const base::UnguessableToken& request_id) const;
private:
base::Optional<cryptauth::RemoteDeviceRef> default_local_device_metadata_;
std::unordered_map<base::UnguessableToken,
cryptauth::RemoteDeviceRef,
base::UnguessableTokenHash>
request_id_to_metadata_map_;
DISALLOW_COPY_AND_ASSIGN(LocalDeviceMetadataManager);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_LOCAL_DEVICE_METADATA_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 "chromeos/services/secure_channel/local_device_metadata_manager.h"
#include <memory>
#include "base/run_loop.h"
#include "base/test/gtest_util.h"
#include "base/unguessable_token.h"
#include "components/cryptauth/remote_device_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace secure_channel {
namespace {
const size_t kNumTestDevices = 2;
} // namespace
class SecureChannelLocalDeviceMetadataManagerTest : public testing::Test {
protected:
SecureChannelLocalDeviceMetadataManagerTest()
: test_device_refs_(
cryptauth::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {}
~SecureChannelLocalDeviceMetadataManagerTest() override = default;
// testing::Test:
void SetUp() override {
manager_ = std::make_unique<LocalDeviceMetadataManager>();
}
cryptauth::RemoteDeviceRef GetDevice(size_t index) {
EXPECT_TRUE(index < kNumTestDevices);
return test_device_refs_[index];
}
LocalDeviceMetadataManager* manager() { return manager_.get(); }
const cryptauth::RemoteDeviceRefList& test_device_refs() {
return test_device_refs_;
}
private:
const cryptauth::RemoteDeviceRefList test_device_refs_;
std::unique_ptr<LocalDeviceMetadataManager> manager_;
DISALLOW_COPY_AND_ASSIGN(SecureChannelLocalDeviceMetadataManagerTest);
};
TEST_F(SecureChannelLocalDeviceMetadataManagerTest, DefaultLocalDevice) {
// No device should be present before one is added.
EXPECT_FALSE(manager()->GetDefaultLocalDeviceMetadata());
// Set the default local device.
manager()->SetDefaultLocalDeviceDataMetadata(test_device_refs()[0]);
EXPECT_EQ(test_device_refs()[0], *manager()->GetDefaultLocalDeviceMetadata());
// Set a new device as the default local device.
manager()->SetDefaultLocalDeviceDataMetadata(test_device_refs()[1]);
EXPECT_EQ(test_device_refs()[1], *manager()->GetDefaultLocalDeviceMetadata());
}
TEST_F(SecureChannelLocalDeviceMetadataManagerTest, LocalDevicePerRequest) {
auto request_id_1 = base::UnguessableToken::Create();
auto request_id_2 = base::UnguessableToken::Create();
// First request.
EXPECT_FALSE(manager()->GetLocalDeviceMetadataForRequest(request_id_1));
manager()->SetLocalDeviceMetadataForRequest(request_id_1,
test_device_refs()[0]);
EXPECT_EQ(test_device_refs()[0],
*manager()->GetLocalDeviceMetadataForRequest(request_id_1));
// Second request.
EXPECT_FALSE(manager()->GetLocalDeviceMetadataForRequest(request_id_2));
manager()->SetLocalDeviceMetadataForRequest(request_id_2,
test_device_refs()[1]);
EXPECT_EQ(test_device_refs()[1],
*manager()->GetLocalDeviceMetadataForRequest(request_id_2));
// Setting new metadata for a request which has already been set should cause
// a crash.
EXPECT_DCHECK_DEATH(manager()->SetLocalDeviceMetadataForRequest(
request_id_1, test_device_refs()[1]));
EXPECT_DCHECK_DEATH(manager()->SetLocalDeviceMetadataForRequest(
request_id_2, test_device_refs()[0]));
}
} // namespace secure_channel
} // namespace chromeos
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