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
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_
#define CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_
#include <memory>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "chrome/browser/touch_to_fill/password_manager/touch_to_fill_controller_webauthn_delegate.h"
#include "chrome/browser/webauthn/shared_types.h"
#include "components/password_manager/core/browser/passkey_credential.h"
#include "components/password_manager/core/browser/password_form.h"
#include "components/webauthn/android/webauthn_client_android.h"
#include "content/public/browser/global_routing_id.h"
namespace content {
class RenderFrameHost;
class WebContents;
} // namespace content
namespace device {
class DiscoverableCredentialMetadata;
}
namespace password_manager {
class KeyboardReplacingSurfaceVisibilityController;
}
class PasswordCredentialController;
class TouchToFillController;
// Helper class for connecting the autofill implementation to the WebAuthn
// request handling for Conditional UI on Android. This is attached to a
// WebContents via SetUserData. It caches a callback that will complete the
// WebAuthn 'get' request when a user selects a credential.
class WebAuthnRequestDelegateAndroid
: public base::SupportsUserData::Data,
public TouchToFillControllerWebAuthnDelegate::CredentialReceiver {
public:
explicit WebAuthnRequestDelegateAndroid(content::WebContents* web_contents);
WebAuthnRequestDelegateAndroid(const WebAuthnRequestDelegateAndroid&) =
delete;
WebAuthnRequestDelegateAndroid& operator=(
const WebAuthnRequestDelegateAndroid&) = delete;
~WebAuthnRequestDelegateAndroid() override;
// Called when a Web Authentication GetAssertion request is received. This
// provides a callback that will complete the request if and when a user
// selects a credential from a touch to fill sheet, and also a closure that
// is invoked if the user starts a hybrid authentication.
void OnWebAuthnRequestPending(
content::RenderFrameHost* frame_host,
std::vector<device::DiscoverableCredentialMetadata> credentials,
webauthn::AssertionMediationType mediation_type,
base::RepeatingCallback<void(const std::vector<uint8_t>& id)>
passkey_or_dismiss_callback,
base::RepeatingCallback<void(std::u16string_view, std::u16string_view)>
password_callback,
base::RepeatingCallback<void()> hybrid_callback,
base::RepeatingCallback<void(webauthn::ImmediateRequestRejectionReason)>
reject_immediate_callback);
// Called when an outstanding request is ended, either because it was aborted
// by the RP, or because it completed successfully. Its main purpose is to
// clean up conditional UI state.
void CleanupWebAuthnRequest(content::RenderFrameHost* frame_host);
// TouchToFillControllerWebAuthnDelegate::CredentialReceiver:
void OnWebAuthnAccountSelected(const std::vector<uint8_t>& id) override;
void OnPasswordCredentialSelected(
const PasswordCredentialPair& password_credential) override;
void OnCredentialSelectionDeclined() override;
void OnHybridSignInSelected() override;
content::WebContents* web_contents() override;
// Returns a delegate associated with the |web_contents|. It creates one if
// one does not already exist.
// The delegate is destroyed along with the WebContents and so should not be
// cached.
static WebAuthnRequestDelegateAndroid* GetRequestDelegate(
content::WebContents* web_contents);
private:
// This takes the RenderFrameHost's GlobalID rather than a pointer, so that
// it can be called asynchronously without having to worry about lifetimes.
void MaybeShowTouchToFillSheet(
content::GlobalRenderFrameHostId render_frame_host_id,
bool isImmediate,
std::vector<password_manager::PasskeyCredential> passkey_credentials,
std::vector<std::unique_ptr<password_manager::PasswordForm>>
password_credentials);
base::RepeatingCallback<void(const std::vector<uint8_t>& user_id)>
passkey_or_dismiss_callback_;
base::RepeatingCallback<void(std::u16string_view, std::u16string_view)>
password_callback_;
base::RepeatingClosure hybrid_callback_;
base::RepeatingCallback<void(webauthn::ImmediateRequestRejectionReason)>
reject_immediate_callback_;
// Controller for using the Touch To Fill bottom sheet for non-conditional
// requests.
std::unique_ptr<TouchToFillController> touch_to_fill_controller_;
std::unique_ptr<
password_manager::KeyboardReplacingSurfaceVisibilityController>
visibility_controller_;
// The WebContents that has this object in its userdata.
raw_ptr<content::WebContents> web_contents_;
bool conditional_request_in_progress_ = false;
std::unique_ptr<PasswordCredentialController> password_controller_;
base::WeakPtrFactory<WebAuthnRequestDelegateAndroid> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_
|