1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <utility>
6 
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "device/fido/fido_authenticator.h"
10 #include "device/fido/fido_constants.h"
11 #include "device/fido/pin.h"
12 #include "device/fido/reset_request_handler.h"
13 
14 namespace device {
15 
ResetRequestHandler(const base::flat_set<FidoTransportProtocol> & supported_transports,ResetSentCallback reset_sent_callback,FinishedCallback finished_callback,std::unique_ptr<FidoDiscoveryFactory> fido_discovery_factory)16 ResetRequestHandler::ResetRequestHandler(
17     const base::flat_set<FidoTransportProtocol>& supported_transports,
18     ResetSentCallback reset_sent_callback,
19     FinishedCallback finished_callback,
20     std::unique_ptr<FidoDiscoveryFactory> fido_discovery_factory)
21     : FidoRequestHandlerBase(fido_discovery_factory.get(),
22                              supported_transports),
23       reset_sent_callback_(std::move(reset_sent_callback)),
24       finished_callback_(std::move(finished_callback)),
25       fido_discovery_factory_(std::move(fido_discovery_factory)) {
26   Start();
27 }
28 
~ResetRequestHandler()29 ResetRequestHandler::~ResetRequestHandler() {
30   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
31 }
32 
DispatchRequest(FidoAuthenticator * authenticator)33 void ResetRequestHandler::DispatchRequest(FidoAuthenticator* authenticator) {
34   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
35 
36   authenticator->GetTouch(base::BindOnce(&ResetRequestHandler::OnTouch,
37                                          weak_factory_.GetWeakPtr(),
38                                          authenticator));
39 }
40 
OnTouch(FidoAuthenticator * authenticator)41 void ResetRequestHandler::OnTouch(FidoAuthenticator* authenticator) {
42   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
43 
44   if (processed_touch_) {
45     return;
46   }
47 
48   processed_touch_ = true;
49   CancelActiveAuthenticators(authenticator->GetId());
50 
51   if (authenticator->SupportedProtocol() != ProtocolVersion::kCtap2) {
52     std::move(finished_callback_)
53         .Run(CtapDeviceResponseCode::kCtap1ErrInvalidCommand);
54     return;
55   }
56 
57   authenticator->Reset(base::BindOnce(&ResetRequestHandler::OnResetComplete,
58                                       weak_factory_.GetWeakPtr()));
59   std::move(reset_sent_callback_).Run();
60 }
61 
OnResetComplete(CtapDeviceResponseCode status,base::Optional<pin::EmptyResponse> response)62 void ResetRequestHandler::OnResetComplete(
63     CtapDeviceResponseCode status,
64     base::Optional<pin::EmptyResponse> response) {
65   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
66   DCHECK(processed_touch_);
67 
68   std::move(finished_callback_).Run(status);
69 }
70 
71 }  // namespace device
72