forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfido_request_handler_base.cc
150 lines (122 loc) · 4.94 KB
/
fido_request_handler_base.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// 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 "device/fido/fido_request_handler_base.h"
#include <utility>
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "device/fido/fido_device.h"
#include "device/fido/fido_task.h"
#include "services/service_manager/public/cpp/connector.h"
namespace device {
namespace {
bool ShouldDeferRequestDispatchToUi(const FidoAuthenticator& authenticator) {
// TODO(hongjunchoi): Change this to be dependent on authenticator transport
// type once UI component is in place.
return false;
}
} // namespace
FidoRequestHandlerBase::AuthenticatorMapObserver::~AuthenticatorMapObserver() =
default;
FidoRequestHandlerBase::FidoRequestHandlerBase(
service_manager::Connector* connector,
const base::flat_set<FidoTransportProtocol>& transports)
: FidoRequestHandlerBase(connector,
transports,
AddPlatformAuthenticatorCallback()) {}
FidoRequestHandlerBase::FidoRequestHandlerBase(
service_manager::Connector* connector,
const base::flat_set<FidoTransportProtocol>& transports,
AddPlatformAuthenticatorCallback add_platform_authenticator)
: add_platform_authenticator_(std::move(add_platform_authenticator)) {
for (const auto transport : transports) {
// Construction of CaBleDiscovery is handled by the implementing class as it
// requires an extension passed on from the relying party.
if (transport == FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy)
continue;
if (transport == FidoTransportProtocol::kInternal) {
// Internal authenticators are injected through
// AddPlatformAuthenticatorCallback.
NOTREACHED();
continue;
}
auto discovery = FidoDiscovery::Create(transport, connector);
if (discovery == nullptr) {
// This can occur in tests when a ScopedVirtualU2fDevice is in effect and
// HID transports are not configured.
continue;
}
discovery->set_observer(this);
discoveries_.push_back(std::move(discovery));
}
}
FidoRequestHandlerBase::~FidoRequestHandlerBase() = default;
void FidoRequestHandlerBase::CancelOngoingTasks(
base::StringPiece exclude_device_id) {
for (auto task_it = active_authenticators_.begin();
task_it != active_authenticators_.end();) {
DCHECK(!task_it->first.empty());
if (task_it->first != exclude_device_id) {
DCHECK(task_it->second);
task_it->second->Cancel();
task_it = active_authenticators_.erase(task_it);
} else {
++task_it;
}
}
}
void FidoRequestHandlerBase::Start() {
for (const auto& discovery : discoveries_)
discovery->Start();
MaybeAddPlatformAuthenticator();
}
void FidoRequestHandlerBase::MaybeAddPlatformAuthenticator() {
if (!add_platform_authenticator_)
return;
auto authenticator = std::move(add_platform_authenticator_).Run();
if (!authenticator)
return;
AddAuthenticator(std::move(authenticator));
}
void FidoRequestHandlerBase::DiscoveryStarted(FidoDiscovery* discovery,
bool success) {
if (discovery->transport() == FidoTransportProtocol::kBluetoothLowEnergy &&
observer_) {
observer_->BluetoothAdapterIsAvailable();
}
}
void FidoRequestHandlerBase::DeviceAdded(FidoDiscovery* discovery,
FidoDevice* device) {
DCHECK(!base::ContainsKey(active_authenticators(), device->GetId()));
AddAuthenticator(CreateAuthenticatorFromDevice(device));
}
std::unique_ptr<FidoDeviceAuthenticator>
FidoRequestHandlerBase::CreateAuthenticatorFromDevice(FidoDevice* device) {
return std::make_unique<FidoDeviceAuthenticator>(device);
}
void FidoRequestHandlerBase::DeviceRemoved(FidoDiscovery* discovery,
FidoDevice* device) {
// Device connection has been lost or device has already been removed.
// Thus, calling CancelTask() is not necessary. Also, below
// ongoing_tasks_.erase() will have no effect for the devices that have been
// already removed due to processing error or due to invocation of
// CancelOngoingTasks().
DCHECK(device);
active_authenticators_.erase(device->GetId());
if (observer_)
observer_->FidoAuthenticatorRemoved(device->GetId());
}
void FidoRequestHandlerBase::AddAuthenticator(
std::unique_ptr<FidoAuthenticator> authenticator) {
DCHECK(authenticator &&
!base::ContainsKey(active_authenticators(), authenticator->GetId()));
FidoAuthenticator* authenticator_ptr = authenticator.get();
active_authenticators_.emplace(authenticator->GetId(),
std::move(authenticator));
if (!ShouldDeferRequestDispatchToUi(*authenticator.get()))
DispatchRequest(authenticator_ptr);
if (observer_)
observer_->FidoAuthenticatorAdded(*authenticator);
}
} // namespace device