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 "content/browser/webauth/authenticator_environment_impl.h"
6 
7 #include <algorithm>
8 #include <utility>
9 
10 #include "base/command_line.h"
11 #include "base/stl_util.h"
12 #include "content/browser/webauth/virtual_authenticator.h"
13 #include "content/browser/webauth/virtual_discovery.h"
14 #include "content/browser/webauth/virtual_fido_discovery_factory.h"
15 #include "device/fido/fido_discovery_factory.h"
16 
17 namespace content {
18 
19 // static
GetInstance()20 AuthenticatorEnvironment* AuthenticatorEnvironment::GetInstance() {
21   return AuthenticatorEnvironmentImpl::GetInstance();
22 }
23 
24 // static
GetInstance()25 AuthenticatorEnvironmentImpl* AuthenticatorEnvironmentImpl::GetInstance() {
26   static base::NoDestructor<AuthenticatorEnvironmentImpl> environment;
27   return environment.get();
28 }
29 
30 AuthenticatorEnvironmentImpl::AuthenticatorEnvironmentImpl() = default;
31 
32 AuthenticatorEnvironmentImpl::~AuthenticatorEnvironmentImpl() = default;
33 
EnableVirtualAuthenticatorFor(FrameTreeNode * node)34 void AuthenticatorEnvironmentImpl::EnableVirtualAuthenticatorFor(
35     FrameTreeNode* node) {
36   // Do not create a new virtual authenticator if there is one already defined
37   // for the |node|.
38   if (base::Contains(virtual_authenticator_managers_, node))
39     return;
40 
41   node->AddObserver(this);
42   virtual_authenticator_managers_[node] =
43       std::make_unique<VirtualAuthenticatorManagerImpl>();
44 }
45 
DisableVirtualAuthenticatorFor(FrameTreeNode * node)46 void AuthenticatorEnvironmentImpl::DisableVirtualAuthenticatorFor(
47     FrameTreeNode* node) {
48   if (!base::Contains(virtual_authenticator_managers_, node))
49     return;
50 
51   node->RemoveObserver(this);
52   virtual_authenticator_managers_.erase(node);
53 }
54 
IsVirtualAuthenticatorEnabledFor(FrameTreeNode * node)55 bool AuthenticatorEnvironmentImpl::IsVirtualAuthenticatorEnabledFor(
56     FrameTreeNode* node) {
57   return MaybeGetVirtualAuthenticatorManager(node) != nullptr;
58 }
59 
60 VirtualAuthenticatorManagerImpl*
MaybeGetVirtualAuthenticatorManager(FrameTreeNode * node)61 AuthenticatorEnvironmentImpl::MaybeGetVirtualAuthenticatorManager(
62     FrameTreeNode* node) {
63   for (; node; node = FrameTreeNode::From(node->parent())) {
64     if (base::Contains(virtual_authenticator_managers_, node)) {
65       return virtual_authenticator_managers_[node].get();
66     }
67   }
68   return nullptr;
69 }
70 
AddVirtualAuthenticatorReceiver(FrameTreeNode * node,mojo::PendingReceiver<blink::test::mojom::VirtualAuthenticatorManager> receiver)71 void AuthenticatorEnvironmentImpl::AddVirtualAuthenticatorReceiver(
72     FrameTreeNode* node,
73     mojo::PendingReceiver<blink::test::mojom::VirtualAuthenticatorManager>
74         receiver) {
75   auto it = virtual_authenticator_managers_.find(node);
76   DCHECK(it != virtual_authenticator_managers_.end());
77   it->second->AddReceiver(std::move(receiver));
78 }
79 
HasVirtualUserVerifyingPlatformAuthenticator(FrameTreeNode * node)80 bool AuthenticatorEnvironmentImpl::HasVirtualUserVerifyingPlatformAuthenticator(
81     FrameTreeNode* node) {
82   VirtualAuthenticatorManagerImpl* authenticator_manager =
83       MaybeGetVirtualAuthenticatorManager(node);
84   if (!authenticator_manager) {
85     return false;
86   }
87   std::vector<VirtualAuthenticator*> authenticators =
88       authenticator_manager->GetAuthenticators();
89   return std::any_of(authenticators.begin(), authenticators.end(),
90                      [](VirtualAuthenticator* a) {
91                        return a->is_user_verifying_platform_authenticator();
92                      });
93 }
94 
95 device::FidoDiscoveryFactory*
MaybeGetDiscoveryFactoryTestOverride()96 AuthenticatorEnvironmentImpl::MaybeGetDiscoveryFactoryTestOverride() {
97   return replaced_discovery_factory_.get();
98 }
99 
ReplaceDefaultDiscoveryFactoryForTesting(std::unique_ptr<device::FidoDiscoveryFactory> factory)100 void AuthenticatorEnvironmentImpl::ReplaceDefaultDiscoveryFactoryForTesting(
101     std::unique_ptr<device::FidoDiscoveryFactory> factory) {
102   replaced_discovery_factory_ = std::move(factory);
103 }
104 
OnFrameTreeNodeDestroyed(FrameTreeNode * node)105 void AuthenticatorEnvironmentImpl::OnFrameTreeNodeDestroyed(
106     FrameTreeNode* node) {
107   DisableVirtualAuthenticatorFor(node);
108 }
109 
110 }  // namespace content
111