Commit 7ae2f35b authored by Ryan Hansberry's avatar Ryan Hansberry Committed by Commit Bot

[CrOS Multidevice] Create SecureChannelClient interface and test double.

SecureChannelClient's full implementation will follow in a subsequent
CL; we are creating the interface and test fake now to unblock other
engineers' work.

Bug: 824568, 752273
Change-Id: Ic7bc054d6a59d1f1b65e7831c4be9c6f77045ad0
Reviewed-on: https://chromium-review.googlesource.com/1083948
Commit-Queue: Ryan Hansberry <hansberry@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565091}
parent 218dabf6
......@@ -179,6 +179,7 @@ source_set("unit_tests") {
":secure_channel",
":test_support",
"//base/test:test_support",
"//chromeos/services/secure_channel/public/cpp/client:unit_tests",
"//chromeos/services/secure_channel/public/cpp/shared",
"//chromeos/services/secure_channel/public/cpp/shared:connection_priority",
"//chromeos/services/secure_channel/public/cpp/shared:test_support",
......
# 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.
source_set("client") {
sources = [
"connection_attempt.cc",
"connection_attempt.h",
"secure_channel_client.h",
"secure_channel_client_impl.cc",
"secure_channel_client_impl.h",
]
deps = [
"//base",
"//chromeos/components/proximity_auth/logging",
"//chromeos/services/secure_channel/public/cpp/shared",
"//chromeos/services/secure_channel/public/mojom",
"//mojo/public/cpp/bindings",
"//services/service_manager/public/cpp",
]
}
static_library("test_support") {
testonly = true
sources = [
":shared",
"fake_secure_channel_client.cc",
"fake_secure_channel_client.h",
]
deps = [
"//base",
"//chromeos/services/secure_channel/public/cpp/client",
"//chromeos/services/secure_channel/public/cpp/shared",
"//chromeos/services/secure_channel/public/mojom",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"secure_channel_client_impl_unittest.cc",
]
deps = [
":client",
":test_support",
"//base",
"//base/test:test_support",
"//chromeos/services/secure_channel/public/cpp/shared",
"//components/cryptauth",
"//components/cryptauth:test_support",
"//services/service_manager/public/cpp:service_test_support",
"//services/service_manager/public/cpp/test:test_support",
"//testing/gtest",
]
}
// 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/public/cpp/client/connection_attempt.h"
namespace chromeos {
namespace secure_channel {
ConnectionAttempt::Delegate::~Delegate() = default;
ConnectionAttempt::ConnectionAttempt() = default;
ConnectionAttempt::~ConnectionAttempt() = default;
void ConnectionAttempt::SetDelegate(Delegate* delegate) {
delegate_ = delegate;
}
void ConnectionAttempt::NotifyConnectionAttemptFailure(
mojom::ConnectionAttemptFailureReason reason) {
if (delegate_) {
delegate_->OnConnectionAttemptFailure(reason);
} else {
PA_LOG(ERROR) << "NotifyConnectionAttemptFailure: No delegate added.";
NOTREACHED();
}
}
void ConnectionAttempt::NotifyConnection(
std::unique_ptr<AuthenticatedChannel> authenticated_channel) {
if (delegate_) {
delegate_->OnConnection(std::move(authenticated_channel));
} else {
PA_LOG(ERROR) << "NotifyConnection: No delegate added.";
NOTREACHED();
}
}
} // 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_PUBLIC_CPP_CLIENT_CONNECTION_ATTEMPT_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_CONNECTION_ATTEMPT_H_
#include "base/macros.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h"
#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
namespace chromeos {
namespace secure_channel {
class AuthenticatedChannel;
// A handle for clients to own while waiting for a connection to establish (or
// fail); it is returned by SecureChannelClient's InitiateConnectionToDevice()
// or ListenForConnectionFromDevice() method. Clients should implement the
// ConnectionAttempt::Delegate interface, and call AddDelegate() on the object
// immediately after receiving it. To cancel a connection attempt, simply delete
// the object. After receiving the OnConnection() callback, it is fine to delete
// the ConnectionAttempt object; the returned AuthenticatedChannel object will
// be the client's way to interface with the API moving forward.
class ConnectionAttempt {
public:
class Delegate {
public:
virtual ~Delegate();
virtual void OnConnectionAttemptFailure(
mojom::ConnectionAttemptFailureReason reason) = 0;
virtual void OnConnection(
std::unique_ptr<AuthenticatedChannel> authenticated_channel) = 0;
};
ConnectionAttempt();
virtual ~ConnectionAttempt();
void SetDelegate(Delegate* delegate);
protected:
void NotifyConnectionAttemptFailure(
mojom::ConnectionAttemptFailureReason reason);
void NotifyConnection(
std::unique_ptr<AuthenticatedChannel> authenticated_channel);
private:
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(ConnectionAttempt);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_CONNECTION_ATTEMPT_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/public/cpp/client/fake_secure_channel_client.h"
#include "chromeos/services/secure_channel/public/cpp/client/connection_attempt.h"
#include "components/cryptauth/remote_device_ref.h"
namespace chromeos {
namespace secure_channel {
FakeSecureChannelClient::ConnectionRequestArguments::ConnectionRequestArguments(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
const ConnectionPriority& connection_priority)
: device_to_connect(device_to_connect),
local_device(local_device),
feature(feature),
connection_priority(connection_priority) {}
FakeSecureChannelClient::ConnectionRequestArguments::
~ConnectionRequestArguments() = default;
FakeSecureChannelClient::FakeSecureChannelClient() = default;
FakeSecureChannelClient::~FakeSecureChannelClient() {
DCHECK(!next_initiate_connection_connection_attempt_);
DCHECK(!next_listen_for_connection_connection_attempt_);
}
std::unique_ptr<ConnectionAttempt>
FakeSecureChannelClient::InitiateConnectionToDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) {
last_initiate_connection_request_arguments_list_.push_back(
std::make_unique<ConnectionRequestArguments>(
device_to_connect, local_device, feature, connection_priority));
return std::move(next_initiate_connection_connection_attempt_);
}
std::unique_ptr<ConnectionAttempt>
FakeSecureChannelClient::ListenForConnectionFromDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) {
last_listen_for_connection_request_arguments_list_.push_back(
std::make_unique<ConnectionRequestArguments>(
device_to_connect, local_device, feature, connection_priority));
return std::move(next_listen_for_connection_connection_attempt_);
}
} // 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_PUBLIC_CPP_CLIENT_FAKE_SECURE_CHANNEL_CLIENT_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_SECURE_CHANNEL_CLIENT_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "chromeos/services/secure_channel/public/cpp/client/secure_channel_client.h"
#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h"
namespace chromeos {
namespace secure_channel {
// Test SecureChannelClient implementation.
class FakeSecureChannelClient : public SecureChannelClient {
public:
struct ConnectionRequestArguments {
public:
ConnectionRequestArguments(cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
const ConnectionPriority& connection_priority);
~ConnectionRequestArguments();
cryptauth::RemoteDeviceRef device_to_connect;
cryptauth::RemoteDeviceRef local_device;
std::string feature;
ConnectionPriority connection_priority;
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionRequestArguments);
};
FakeSecureChannelClient();
~FakeSecureChannelClient() override;
void set_initiate_connection_connection_attempt(
std::unique_ptr<ConnectionAttempt> attempt) {
next_initiate_connection_connection_attempt_ = std::move(attempt);
}
void set_listen_for_connection_connection_attempt(
std::unique_ptr<ConnectionAttempt> attempt) {
next_listen_for_connection_connection_attempt_ = std::move(attempt);
}
std::vector<ConnectionRequestArguments*>
last_initiate_connection_request_arguments_list() {
std::vector<ConnectionRequestArguments*> arguments_list_raw_;
std::transform(last_initiate_connection_request_arguments_list_.begin(),
last_initiate_connection_request_arguments_list_.end(),
std::back_inserter(arguments_list_raw_),
[](const auto& arguments) { return arguments.get(); });
return arguments_list_raw_;
}
std::vector<ConnectionRequestArguments*>
last_listen_for_connection_request_arguments_list() {
std::vector<ConnectionRequestArguments*> arguments_list_raw_;
std::transform(last_listen_for_connection_request_arguments_list_.begin(),
last_listen_for_connection_request_arguments_list_.end(),
std::back_inserter(arguments_list_raw_),
[](const auto& arguments) { return arguments.get(); });
return arguments_list_raw_;
}
// SecureChannelClient:
std::unique_ptr<ConnectionAttempt> InitiateConnectionToDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) override;
std::unique_ptr<ConnectionAttempt> ListenForConnectionFromDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) override;
private:
std::unique_ptr<ConnectionAttempt>
next_initiate_connection_connection_attempt_;
std::unique_ptr<ConnectionAttempt>
next_listen_for_connection_connection_attempt_;
std::vector<std::unique_ptr<ConnectionRequestArguments>>
last_initiate_connection_request_arguments_list_;
std::vector<std::unique_ptr<ConnectionRequestArguments>>
last_listen_for_connection_request_arguments_list_;
DISALLOW_COPY_AND_ASSIGN(FakeSecureChannelClient);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_SECURE_CHANNEL_CLIENT_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.
#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_SECURE_CHANNEL_CLIENT_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_SECURE_CHANNEL_CLIENT_H_
#include <string>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
#include "components/cryptauth/remote_device_ref.h"
namespace chromeos {
namespace secure_channel {
class ConnectionAttempt;
// Provides clients access to the SecureChannel API.
//
// Clients can choose to either initiate a connection to another device, or
// listen for an expected connection from another device. Device details are
// encapsulated in the RemoteDeviceRef; see the DeviceSync API for information
// on how to retrieve this data.
//
// Calls to initiate or listen for a connection take identical arguments:
// 1) |device_to_connect|:
// The RemoteDeviceRef which refers to the device a connection should be made
// to.
// 2) |local_device|:
// The RemoteDeviceRef which refers to the local device. |local_device| and
// |device_to_connect| must be in the same user account.
// 3) |feature|:
// A unique string identifier for your feature. If multiple clients make a
// a connection request between the same |device_to_connect| and
// |local_device| but different features, those clients will share the same
// underlying connection, but their messages will be routed to the correct
// clients based on the |feature| identifier of the message.
// 4) |connection_priority|:
// The priority of this connection request. Please make higher priority
// requests only when necessary.
//
// Calls to initiate or listen for a connection will return a ConnectionAttempt
// object. Please see the documentation on ConnectionAttempt to learn how to
// correctly use it.
//
// Note: Right now, the SecureChannel API only offers connections to other
// devices over BLE. In the future, more connection mediums will be offered.
class SecureChannelClient {
public:
virtual ~SecureChannelClient() = default;
virtual std::unique_ptr<ConnectionAttempt> InitiateConnectionToDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) = 0;
virtual std::unique_ptr<ConnectionAttempt> ListenForConnectionFromDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) = 0;
protected:
SecureChannelClient() = default;
private:
DISALLOW_COPY_AND_ASSIGN(SecureChannelClient);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_SECURE_CHANNEL_CLIENT_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/public/cpp/client/secure_channel_client_impl.h"
#include "base/no_destructor.h"
#include "chromeos/services/secure_channel/public/cpp/client/connection_attempt.h"
namespace chromeos {
namespace secure_channel {
// static
SecureChannelClientImpl::Factory*
SecureChannelClientImpl::Factory::test_factory_ = nullptr;
// static
SecureChannelClientImpl::Factory* SecureChannelClientImpl::Factory::Get() {
if (test_factory_)
return test_factory_;
static base::NoDestructor<Factory> factory;
return factory.get();
}
// static
void SecureChannelClientImpl::Factory::SetInstanceForTesting(
Factory* test_factory) {
test_factory_ = test_factory;
}
SecureChannelClientImpl::Factory::~Factory() = default;
std::unique_ptr<SecureChannelClient>
SecureChannelClientImpl::Factory::BuildInstance() {
return base::WrapUnique(new SecureChannelClientImpl());
}
SecureChannelClientImpl::SecureChannelClientImpl() = default;
SecureChannelClientImpl::~SecureChannelClientImpl() = default;
std::unique_ptr<ConnectionAttempt>
SecureChannelClientImpl::InitiateConnectionToDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) {
return nullptr;
}
std::unique_ptr<ConnectionAttempt>
SecureChannelClientImpl::ListenForConnectionFromDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) {
return nullptr;
}
} // 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_PUBLIC_CPP_CLIENT_SECURE_CHANNEL_CLIENT_IMPL_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_SECURE_CHANNEL_CLIENT_IMPL_H_
#include "chromeos/services/secure_channel/public/cpp/client/secure_channel_client.h"
namespace chromeos {
namespace secure_channel {
// Provides clients access to the SecureChannel API.
class SecureChannelClientImpl : public SecureChannelClient {
public:
public:
class Factory {
public:
static Factory* Get();
static void SetInstanceForTesting(Factory* test_factory);
virtual ~Factory();
virtual std::unique_ptr<SecureChannelClient> BuildInstance();
private:
static Factory* test_factory_;
};
~SecureChannelClientImpl() override;
private:
friend class SecureChannelClientImplTest;
SecureChannelClientImpl();
// SecureChannelClient:
std::unique_ptr<ConnectionAttempt> InitiateConnectionToDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) override;
std::unique_ptr<ConnectionAttempt> ListenForConnectionFromDevice(
cryptauth::RemoteDeviceRef device_to_connect,
cryptauth::RemoteDeviceRef local_device,
const std::string& feature,
ConnectionPriority connection_priority) override;
DISALLOW_COPY_AND_ASSIGN(SecureChannelClientImpl);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_SECURE_CHANNEL_CLIENT_IMPL_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/public/cpp/client/secure_channel_client_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace secure_channel {
class SecureChannelClientImplTest : public testing::Test {
protected:
SecureChannelClientImplTest() = default;
// testing::Test:
void SetUp() override {
client_ = SecureChannelClientImpl::Factory::Get()->BuildInstance();
}
std::unique_ptr<SecureChannelClient> client_;
private:
DISALLOW_COPY_AND_ASSIGN(SecureChannelClientImplTest);
};
TEST_F(SecureChannelClientImplTest, Test) {
// TODO(hansberry): Implement.
}
} // 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