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 <utility>
8 
9 #include "base/command_line.h"
10 #include "base/stl_util.h"
11 #include "content/browser/webauth/virtual_discovery.h"
12 #include "content/browser/webauth/virtual_fido_discovery_factory.h"
13 #include "device/fido/fido_discovery_factory.h"
14 
15 namespace content {
16 
17 // static
GetInstance()18 AuthenticatorEnvironment* AuthenticatorEnvironment::GetInstance() {
19   return AuthenticatorEnvironmentImpl::GetInstance();
20 }
21 
22 // static
GetInstance()23 AuthenticatorEnvironmentImpl* AuthenticatorEnvironmentImpl::GetInstance() {
24   static base::NoDestructor<AuthenticatorEnvironmentImpl> environment;
25   return environment.get();
26 }
27 
28 AuthenticatorEnvironmentImpl::AuthenticatorEnvironmentImpl() = default;
29 
30 AuthenticatorEnvironmentImpl::~AuthenticatorEnvironmentImpl() = default;
31 
32 device::FidoDiscoveryFactory*
GetDiscoveryFactoryOverride(FrameTreeNode * node)33 AuthenticatorEnvironmentImpl::GetDiscoveryFactoryOverride(FrameTreeNode* node) {
34   auto* factory = GetVirtualFactoryFor(node);
35   if (factory)
36     return factory;
37   return replaced_discovery_factory_.get();
38 }
39 
EnableVirtualAuthenticatorFor(FrameTreeNode * node)40 void AuthenticatorEnvironmentImpl::EnableVirtualAuthenticatorFor(
41     FrameTreeNode* node) {
42   // Do not create a new virtual authenticator if there is one already defined
43   // for the |node|.
44   if (base::Contains(virtual_discovery_factories_, node))
45     return;
46 
47   node->AddObserver(this);
48   virtual_discovery_factories_[node] =
49       std::make_unique<VirtualFidoDiscoveryFactory>();
50 }
51 
DisableVirtualAuthenticatorFor(FrameTreeNode * node)52 void AuthenticatorEnvironmentImpl::DisableVirtualAuthenticatorFor(
53     FrameTreeNode* node) {
54   if (!base::Contains(virtual_discovery_factories_, node))
55     return;
56 
57   node->RemoveObserver(this);
58   virtual_discovery_factories_.erase(node);
59 }
60 
GetVirtualFactoryFor(FrameTreeNode * node)61 VirtualFidoDiscoveryFactory* AuthenticatorEnvironmentImpl::GetVirtualFactoryFor(
62     FrameTreeNode* node) {
63   do {
64     if (base::Contains(virtual_discovery_factories_, node)) {
65       return virtual_discovery_factories_[node].get();
66     }
67   } while ((node = node->parent()));
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* factory = GetVirtualFactoryFor(node);
76   DCHECK(factory);
77   factory->AddReceiver(std::move(receiver));
78 }
79 
OnDiscoveryDestroyed(VirtualFidoDiscovery * discovery)80 void AuthenticatorEnvironmentImpl::OnDiscoveryDestroyed(
81     VirtualFidoDiscovery* discovery) {
82   for (auto& it : virtual_discovery_factories_) {
83     it.second->OnDiscoveryDestroyed(discovery);
84   }
85 }
86 
ReplaceDefaultDiscoveryFactoryForTesting(std::unique_ptr<device::FidoDiscoveryFactory> factory)87 void AuthenticatorEnvironmentImpl::ReplaceDefaultDiscoveryFactoryForTesting(
88     std::unique_ptr<device::FidoDiscoveryFactory> factory) {
89   replaced_discovery_factory_ = std::move(factory);
90 }
91 
OnFrameTreeNodeDestroyed(FrameTreeNode * node)92 void AuthenticatorEnvironmentImpl::OnFrameTreeNodeDestroyed(
93     FrameTreeNode* node) {
94   DisableVirtualAuthenticatorFor(node);
95 }
96 
97 }  // namespace content
98