| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_WEBID_FEDERATED_AUTH_REQUEST_IMPL_H_ |
| #define CONTENT_BROWSER_WEBID_FEDERATED_AUTH_REQUEST_IMPL_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/containers/queue.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/time/time.h" |
| #include "content/browser/webid/fedcm_accounts_fetcher.h" |
| #include "content/browser/webid/fedcm_metrics.h" |
| #include "content/browser/webid/fedcm_url_computations.h" |
| #include "content/browser/webid/federated_sd_jwt_handler.h" |
| #include "content/browser/webid/identity_provider_info.h" |
| #include "content/browser/webid/identity_registry.h" |
| #include "content/browser/webid/identity_registry_delegate.h" |
| #include "content/browser/webid/idp_network_request_manager.h" |
| #include "content/browser/webid/jwt_signer.h" |
| #include "content/browser/webid/sd_jwt.h" |
| #include "content/common/content_export.h" |
| #include "content/public/browser/document_service.h" |
| #include "content/public/browser/federated_auth_autofill_source.h" |
| #include "content/public/browser/federated_identity_api_permission_context_delegate.h" |
| #include "content/public/browser/federated_identity_permission_context_delegate.h" |
| #include "content/public/browser/identity_request_dialog_controller.h" |
| #include "content/public/browser/web_contents.h" |
| #include "third_party/blink/public/mojom/credentialmanagement/credential_manager.mojom.h" |
| #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h" |
| #include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h" |
| #include "url/gurl.h" |
| |
| namespace gfx { |
| class Image; |
| } |
| |
| namespace blink::common::webid { |
| struct LoginStatusOptions; |
| } // namespace blink::common::webid |
| |
| namespace content { |
| |
| class FederatedAuthDisconnectRequest; |
| class FederatedAuthUserInfoRequest; |
| class FederatedIdentityApiPermissionContextDelegate; |
| class FederatedIdentityAutoReauthnPermissionContextDelegate; |
| class FederatedIdentityPermissionContextDelegate; |
| class RenderFrameHost; |
| class FederatedSdJwtHandler; |
| |
| using blink::mojom::IdentityProviderGetParametersPtr; |
| using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>; |
| using IdentityProviderGetInfo = FedCmAccountsFetcher::IdentityProviderGetInfo; |
| using IdentityRequestAccountPtr = |
| scoped_refptr<content::IdentityRequestAccount>; |
| using MediationRequirement = ::password_manager::CredentialMediationRequirement; |
| using RpMode = blink::mojom::RpMode; |
| using TokenError = IdentityCredentialTokenError; |
| |
| // FederatedAuthRequestImpl handles mojo connections from the renderer to |
| // fulfill WebID-related requests. |
| // |
| // In practice, it is owned and managed by a RenderFrameHost. It accomplishes |
| // that via subclassing DocumentService, which observes the lifecycle of a |
| // RenderFrameHost and manages its own memory. |
| // Create() creates a self-managed instance of FederatedAuthRequestImpl and |
| // binds it to the receiver. |
| class CONTENT_EXPORT FederatedAuthRequestImpl |
| : public DocumentService<blink::mojom::FederatedAuthRequest>, |
| public FederatedIdentityPermissionContextDelegate:: |
| IdpSigninStatusObserver, |
| public IdentityRegistryDelegate, |
| public FederatedAuthAutofillSource { |
| public: |
| static constexpr char kWildcardDomainHint[] = "any"; |
| |
| static void Create(RenderFrameHost*, |
| mojo::PendingReceiver<blink::mojom::FederatedAuthRequest>); |
| static FederatedAuthRequestImpl& CreateForTesting( |
| RenderFrameHost&, |
| FederatedIdentityApiPermissionContextDelegate*, |
| FederatedIdentityAutoReauthnPermissionContextDelegate*, |
| FederatedIdentityPermissionContextDelegate*, |
| IdentityRegistry*, |
| mojo::PendingReceiver<blink::mojom::FederatedAuthRequest>); |
| |
| FederatedAuthRequestImpl(const FederatedAuthRequestImpl&) = delete; |
| FederatedAuthRequestImpl& operator=(const FederatedAuthRequestImpl&) = delete; |
| |
| ~FederatedAuthRequestImpl() override; |
| |
| // blink::mojom::FederatedAuthRequest: |
| void RequestToken(std::vector<blink::mojom::IdentityProviderGetParametersPtr> |
| idp_get_params_ptrs, |
| MediationRequirement requirement, |
| RequestTokenCallback) override; |
| void RequestUserInfo(blink::mojom::IdentityProviderConfigPtr provider, |
| RequestUserInfoCallback) override; |
| void CancelTokenRequest() override; |
| void ResolveTokenRequest(const std::optional<std::string>& account_id, |
| const std::string& token, |
| ResolveTokenRequestCallback callback) override; |
| void SetIdpSigninStatus( |
| const url::Origin& origin, |
| blink::mojom::IdpSigninStatus status, |
| const std::optional<::blink::common::webid::LoginStatusOptions>& options) |
| override; |
| void RegisterIdP(const ::GURL& idp, RegisterIdPCallback) override; |
| void UnregisterIdP(const ::GURL& idp, UnregisterIdPCallback) override; |
| |
| void CloseModalDialogView() override; |
| void PreventSilentAccess(PreventSilentAccessCallback callback) override; |
| void Disconnect(blink::mojom::IdentityCredentialDisconnectOptionsPtr options, |
| DisconnectCallback) override; |
| |
| // FederatedIdentityPermissionContextDelegate::IdpSigninStatusObserver: |
| void OnIdpSigninStatusReceived(const url::Origin& idp_config_origin, |
| bool idp_signin_status) override; |
| |
| void SetNetworkManagerForTests( |
| std::unique_ptr<IdpNetworkRequestManager> manager); |
| void SetDialogControllerForTests( |
| std::unique_ptr<IdentityRequestDialogController> controller); |
| |
| // content::FederatedIdentityModalDialogViewDelegate: |
| void OnClose() override; |
| bool OnResolve(GURL idp_config_url, |
| const std::optional<std::string>& account_id, |
| const std::string& token) override; |
| void OnOriginMismatch(Method method, |
| const url::Origin& expected, |
| const url::Origin& actual) override; |
| |
| // content::FederatedAuthAutofillSource |
| const std::optional<std::vector<IdentityRequestAccountPtr>> |
| GetAutofillSuggestions() const override; |
| void NotifyAutofillSuggestionAccepted( |
| const GURL& idp, |
| const std::string& account_id, |
| bool show_modal, |
| OnFederatedTokenReceivedCallback callback) override; |
| |
| // To be called on the FederatedAuthRequest object corresponding to a |
| // popup opened by ShowModalDialog, specifically for the case when |
| // ShowModalDialog returned null (particularly Android). In that case, |
| // we can only set up the IdentityRegistry object when we get a call |
| // from the popup context. |
| // Returns false when no identity registry could be created (e.g. this |
| // is not in a context created by ShowModalDialog). |
| bool SetupIdentityRegistryFromPopup(); |
| |
| // Rejects the pending request if it has not been resolved naturally yet. |
| void OnRejectRequest(); |
| |
| // Returns whether the API is enabled or not. |
| FederatedIdentityApiPermissionContextDelegate::PermissionStatus |
| GetApiPermissionStatus(); |
| |
| // For use by the devtools protocol for browser automation. |
| IdentityRequestDialogController* GetDialogController() { |
| return request_dialog_controller_.get(); |
| } |
| |
| const std::vector<IdentityProviderDataPtr>& GetSortedIdpData() const { |
| return idp_data_for_display_; |
| } |
| |
| const std::vector<IdentityRequestAccountPtr>& GetAccounts() const { |
| return accounts_; |
| } |
| |
| MediationRequirement GetMediationRequirement() const { |
| return mediation_requirement_; |
| } |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum DialogType { |
| kNone = 0, |
| kSelectAccount = 1, |
| kAutoReauth = 2, |
| kConfirmIdpLogin = 3, |
| kError = 4, |
| // Popups are not technically dialogs in the strict sense, but because they |
| // are mutually exclusive with browser UI dialogs we use this enum for them |
| // as well. |
| kLoginToIdpPopup = 5, |
| kContinueOnPopup = 6, |
| kErrorUrlPopup = 7, |
| |
| kMaxValue = kErrorUrlPopup |
| }; |
| |
| DialogType GetDialogType() const { return dialog_type_; } |
| |
| enum IdentitySelectionType { kExplicit, kAutoPassive, kAutoActive }; |
| |
| bool ShouldNotifyDevtoolsForDialogType(DialogType type); |
| |
| void AcceptAccountsDialogForDevtools(const GURL& config_url, |
| const IdentityRequestAccount& account); |
| void DismissAccountsDialogForDevtools(bool should_embargo); |
| void AcceptConfirmIdpLoginDialogForDevtools(); |
| void DismissConfirmIdpLoginDialogForDevtools(); |
| bool UseAnotherAccountForDevtools(const IdentityProviderData& provider); |
| bool HasMoreDetailsButtonForDevtools(); |
| void ClickErrorDialogGotItForDevtools(); |
| void ClickErrorDialogMoreDetailsForDevtools(); |
| void DismissErrorDialogForDevtools(); |
| |
| // Whether we can show the continue_on popup (not using mediation: silent, |
| // etc.) |
| bool CanShowContinueOnPopup() const; |
| |
| bool HasUserTriedToSignInToIdp(const GURL& idp_config_url) { |
| return idps_user_tried_to_signin_to_.contains(idp_config_url); |
| } |
| |
| FedCmUseOtherAccountResult ComputeUseOtherAccountResult( |
| blink::mojom::FederatedAuthRequestResult result, |
| const std::optional<GURL>& selected_idp_config_url); |
| |
| void SetIdpLoginInfo(const GURL& idp_login_url, |
| const std::string& login_hint, |
| const std::string& domain_hint); |
| void SetWellKnownAndConfigFetchedTime(base::TimeTicks time); |
| |
| // Called when there is an error in fetching information to show the prompt |
| // for a given IDP - `idp_info`, but we do not need to show failure UI for the |
| // IDP. |
| void OnFetchDataForIdpFailed( |
| std::unique_ptr<IdentityProviderInfo> idp_info, |
| blink::mojom::FederatedAuthRequestResult result, |
| std::optional<content::FedCmRequestIdTokenStatus> token_status, |
| bool should_delay_callback); |
| |
| // Called when all of the data needed to display the FedCM prompt has been |
| // fetched for `idp_info`. Accounts should be moved instead of copied to this |
| // function. |
| void OnFetchDataForIdpSucceeded( |
| std::vector<IdentityRequestAccountPtr> accounts, |
| std::unique_ptr<IdentityProviderInfo> idp_info); |
| |
| void MaybeShowActiveModeModalDialog(const GURL& idp_config_url, |
| const GURL& idp_login_url); |
| |
| void SetAccountsFetchedTime(base::TimeTicks time) { |
| accounts_fetched_time_ = time; |
| } |
| void SetClientMetadataFetchedTime(base::TimeTicks time) { |
| client_metadata_fetched_time_ = time; |
| } |
| |
| url::Origin GetEmbeddingOrigin() const; |
| |
| // TODO(crbug.com/417197032): Remove these once code has been refactored. |
| base::flat_map<GURL, IdentityProviderGetInfo>& GetTokenRequestGetInfos() { |
| return token_request_get_infos_; |
| } |
| GURL login_url() { return login_url_; } |
| bool HadAccoundIdBeforeLogin(const std::string& account_id) { |
| return account_ids_before_login_.contains(account_id); |
| } |
| // Return the FedCmMetrics for use by FedCmAccountsFetcher. |
| // TODO(crbug.com/417784830): Remove this once code has been refactored and |
| // FedCmAccountsFetcher can hold a raw pointer to FedCmMetrics. |
| FedCmMetrics* fedcm_metrics() { return fedcm_metrics_.get(); } |
| |
| // Called when there is an error fetching information to show the prompt for a |
| // given IDP, and because of the mismatch this IDP must be present in the |
| // dialog we show to the user. |
| void OnIdpMismatch(std::unique_ptr<IdentityProviderInfo> idp_info); |
| |
| void CompleteRequestWithError( |
| blink::mojom::FederatedAuthRequestResult result, |
| std::optional<content::FedCmRequestIdTokenStatus> token_status, |
| bool should_delay_callback); |
| |
| // Completes request. Displays a dialog if there is an error and the error is |
| // during a fetch triggered by an IdP sign-in status change. |
| void CompleteRequest( |
| blink::mojom::FederatedAuthRequestResult result, |
| std::optional<content::FedCmRequestIdTokenStatus> token_status, |
| std::optional<TokenError> token_error, |
| const std::optional<GURL>& selected_idp_config_url, |
| const std::string& token, |
| bool should_delay_callback); |
| |
| private: |
| friend class FederatedAuthRequestImplTest; |
| |
| struct FetchData { |
| FetchData(); |
| ~FetchData(); |
| |
| // Set of config URLs of IDPs that have yet to be processed. |
| std::set<GURL> pending_idps; |
| |
| // Whether accounts endpoint fetch succeeded for at least one IdP. |
| bool did_succeed_for_at_least_one_idp{false}; |
| }; |
| |
| FederatedAuthRequestImpl( |
| RenderFrameHost&, |
| FederatedIdentityApiPermissionContextDelegate*, |
| FederatedIdentityAutoReauthnPermissionContextDelegate*, |
| FederatedIdentityPermissionContextDelegate*, |
| IdentityRegistry*, |
| mojo::PendingReceiver<blink::mojom::FederatedAuthRequest>); |
| |
| bool HasPendingRequest() const; |
| |
| // Fetch well-known, config, accounts and client metadata endpoints for |
| // passed-in IdPs. Uses parameters from `token_request_get_infos_`. |
| void FetchEndpointsForIdps(const std::set<GURL>& idp_config_urls); |
| |
| std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> |
| MaybeAddRegisteredProviders( |
| std::vector<blink::mojom::IdentityProviderRequestOptionsPtr>& providers); |
| |
| void MaybeShowAccountsDialog(); |
| void ShowModalDialog(DialogType dialog_type, |
| const GURL& idp_config_url, |
| const GURL& url_to_show); |
| void ShowErrorDialog(const GURL& idp_config_url, |
| IdpNetworkRequestManager::FetchStatus status, |
| std::optional<TokenError> error); |
| // Called when we should show a failure dialog in the case where a single IDP |
| // account fetch resulted in a mismatch with its login status. |
| void ShowSingleIdpFailureDialog(); |
| void OnAccountsDisplayed(); |
| |
| void OnAccountSelected(const GURL& idp_config_url, |
| const std::string& account_id, |
| bool is_sign_in); |
| void OnDismissFailureDialog( |
| IdentityRequestDialogController::DismissReason dismiss_reason); |
| void OnDismissErrorDialog( |
| const GURL& idp_config_url, |
| IdpNetworkRequestManager::FetchStatus status, |
| IdentityRequestDialogController::DismissReason dismiss_reason); |
| void OnDialogDismissed( |
| IdentityRequestDialogController::DismissReason dismiss_reason); |
| void CompleteTokenRequest(const GURL& idp_config_url, |
| IdpNetworkRequestManager::FetchStatus status, |
| std::optional<std::string> token, |
| std::optional<TokenError> token_error, |
| bool should_delay_callback); |
| void OnTokenResponseReceived( |
| blink::mojom::IdentityProviderRequestOptionsPtr idp, |
| IdpNetworkRequestManager::FetchStatus status, |
| IdpNetworkRequestManager::TokenResult result); |
| void OnContinueOnResponseReceived( |
| blink::mojom::IdentityProviderRequestOptionsPtr idp, |
| IdpNetworkRequestManager::FetchStatus status, |
| const GURL& url); |
| |
| // Called after we get at token (either from the ID assertion endpoint or |
| // from IdentityProvider.resolve) to update our various permissions. |
| void MarkUserAsSignedIn(const GURL& idp_config_url, |
| const std::string& account_id); |
| |
| void ProcessSdJwt(const GURL& selected_idp_config_url, |
| const std::string& token); |
| void OnDisclosureParsed(base::RepeatingClosure cb, |
| const std::string& json, |
| data_decoder::DataDecoder::ValueOrError result); |
| void OnSdJwtParsed(const GURL& selected_idp_config_url, |
| const sdjwt::Jwt& token); |
| void CompleteUserInfoRequest( |
| FederatedAuthUserInfoRequest* request, |
| RequestUserInfoCallback callback, |
| blink::mojom::RequestUserInfoStatus status, |
| std::optional<std::vector<blink::mojom::IdentityUserInfoPtr>> user_info); |
| |
| // When two APIs that are associated with the same frame, hence |
| // fedcm_metrics_, are triggered concurrently, we need to reset |
| // `fedcm_metrics` to record UKM for the first request when it's completed and |
| // recreate one for the second if needed. |
| void HandleMetricsForPotentialConcurrentRequests(); |
| |
| // Validates the input from the renderer and signals to terminate the request |
| // if needed. |
| bool ShouldTerminateRequest( |
| const std::vector<IdentityProviderGetParametersPtr>& idp_get_params_ptrs, |
| const MediationRequirement& requirement); |
| |
| // If a new request is associated with active mode, it can replace the pending |
| // request with passive mode. Otherwise a new request will be cancelled when |
| // there's a pending request. Returns `true` if the new request needs to be |
| // cancelled. |
| bool HandlePendingRequestAndCancelNewRequest( |
| const std::vector<GURL>& old_idp_order, |
| const std::vector<IdentityProviderGetParametersPtr>& idps, |
| const MediationRequirement& requirement); |
| |
| void CleanUp(); |
| |
| std::unique_ptr<IdpNetworkRequestManager> CreateNetworkManager(); |
| std::unique_ptr<IdentityRequestDialogController> CreateDialogController(); |
| |
| // Creates an inspector issue related to a federated authentication request to |
| // the Issues panel in DevTools. |
| void AddDevToolsIssue(blink::mojom::FederatedAuthRequestResult result); |
| |
| // Adds a console error message related to a federated authentication request |
| // issue. The Issues panel is preferred, but for now we also surface console |
| // error messages since it is much simpler to add. |
| void AddConsoleErrorMessage(blink::mojom::FederatedAuthRequestResult result); |
| |
| // Returns true and the `IdentityProviderData` + `IdentityRequestAccount` for |
| // the only returning account. Returns false if there are multiple returning |
| // accounts or no returning account. |
| bool GetAccountForAutoReauthn(IdentityProviderDataPtr* out_idp_data, |
| IdentityRequestAccountPtr* out_account); |
| |
| // Check if auto re-authn is available so we can skip fetching accounts if the |
| // auto re-authn flow is guaranteed to fail. |
| bool ShouldFailBeforeFetchingAccounts(const GURL& config_url); |
| |
| // Check if the site requires user mediation due to a previous |
| // `preventSilentAccess` call. |
| bool RequiresUserMediation(); |
| void SetRequiresUserMediation(bool requires_user_mediation, |
| base::OnceClosure callback); |
| |
| // Trigger a dialog to prompt the user to login to the IdP. `can_append_hints` |
| // is true if the caller allows the login url to be augmented with login and |
| // domain hints. |
| void LoginToIdP(bool can_append_hints, |
| const GURL& idp_config_url, |
| GURL login_url); |
| |
| void CompleteDisconnectRequest(DisconnectCallback callback, |
| blink::mojom::DisconnectStatus status); |
| |
| void RecordErrorMetrics( |
| blink::mojom::IdentityProviderRequestOptionsPtr idp, |
| IdpNetworkRequestManager::FedCmTokenResponseType token_response_type, |
| std::optional<IdpNetworkRequestManager::FedCmErrorDialogType> |
| error_dialog_type, |
| std::optional<IdpNetworkRequestManager::FedCmErrorUrlType> |
| error_url_type); |
| |
| void OnRegisterIdPPermissionResponse(RegisterIdPCallback callback, |
| const GURL& idp, |
| bool accepted); |
| void MaybeCreateFedCmMetrics(); |
| |
| bool IsNewlyLoggedIn(const IdentityRequestAccount& account); |
| |
| RpMode GetRpMode() const { return rp_mode_; } |
| |
| RelyingPartyData CreateRpData() const; |
| |
| std::unique_ptr<IdpNetworkRequestManager> network_manager_; |
| std::unique_ptr<IdentityRequestDialogController> request_dialog_controller_; |
| |
| // Replacements for testing. |
| std::unique_ptr<IdpNetworkRequestManager> mock_network_manager_; |
| std::unique_ptr<IdentityRequestDialogController> mock_dialog_controller_; |
| |
| // Helper that records FedCM UMA and UKM metrics. Initialized in the |
| // RequestToken() method, so all metrics must be recorded after that. |
| std::unique_ptr<FedCmMetrics> fedcm_metrics_; |
| |
| // Populated by OnFetchDataForIdpSucceeded() and OnIdpMismatch(). |
| base::flat_map<GURL, std::unique_ptr<IdentityProviderInfo>> idp_infos_; |
| // Populated by MaybeShowAccountsDialog(). |
| std::vector<IdentityProviderDataPtr> idp_data_for_display_; |
| |
| // Populated by OnFetchDataForIdpSucceeded(). Contains the accounts of each |
| // IDP. Used to later set accounts_ in the order in which the IDPs are |
| // requested. |
| base::flat_map<GURL, std::vector<IdentityRequestAccountPtr>> idp_accounts_; |
| // The accounts to be displayed by the UI. |
| std::vector<IdentityRequestAccountPtr> accounts_; |
| // The newly logged in accounts, to be prioritized by the UI. Subset of |
| // `accounts_`. |
| std::vector<IdentityRequestAccountPtr> new_accounts_; |
| |
| // Contains the set of account IDs of an IDP before a login URL is displayed |
| // to the user. Used to compute the account ID of the account that the user |
| // logs in to. Populated by LoginToIdP(). |
| base::flat_set<std::string> account_ids_before_login_; |
| |
| // Maps the login URL to the info that may be added as query parameters to |
| // that URL. Populated by OnAllConfigAndWellKnownFetched(). |
| base::flat_map<GURL, IdentityProviderLoginUrlInfo> idp_login_infos_; |
| |
| raw_ptr<FederatedIdentityApiPermissionContextDelegate> |
| api_permission_delegate_ = nullptr; |
| raw_ptr<FederatedIdentityAutoReauthnPermissionContextDelegate> |
| auto_reauthn_permission_delegate_ = nullptr; |
| raw_ptr<FederatedIdentityPermissionContextDelegate> permission_delegate_ = |
| nullptr; |
| raw_ptr<IdentityRegistry> identity_registry_ = nullptr; |
| |
| // The account that was selected by the user. This is only applicable to the |
| // mediation flow. |
| std::string account_id_; |
| base::TimeTicks start_time_; |
| base::TimeTicks well_known_and_config_fetched_time_; |
| base::TimeTicks accounts_fetched_time_; |
| base::TimeTicks client_metadata_fetched_time_; |
| base::TimeTicks ready_to_display_accounts_dialog_time_; |
| base::TimeTicks accounts_dialog_display_time_; |
| base::TimeTicks select_account_time_; |
| base::TimeTicks id_assertion_response_time_; |
| bool errors_logged_to_console_{false}; |
| // This gets set at the beginning of a request. It indicates whether we |
| // should bypass the delay to notify the renderer, for use in automated |
| // tests when the delay is irrelevant to the test but slows it down |
| // unncessarily. |
| bool should_complete_request_immediately_{false}; |
| // While there could be both token request and user info request when a user |
| // visits a site, it's worth noting that they must be from different render |
| // frames. e.g. one top frame rp.example and one iframe idp.example. |
| // Therefore, |
| // 1. if one of the requests exists, the other one shouldn't. e.g. if the |
| // iframe requests user info, it cannot request token at the same time. |
| // 2. the user info request should not set "HasPendingRequest" on the page |
| // (multiple per page). It's OK to have multiple concurrent user info requests |
| // since there's no browser UI involved. e.g. rp.example embeds |
| // iframe1.example and iframe2.example. Both iframes can request user info |
| // simultaneously. |
| RequestTokenCallback auth_request_token_callback_; |
| |
| OnFederatedTokenReceivedCallback token_received_callback_for_autofill_; |
| |
| std::unique_ptr<FedCmAccountsFetcher> fedcm_accounts_fetcher_; |
| |
| std::unique_ptr<FederatedSdJwtHandler> federated_sdjwt_handler_; |
| |
| // Set of pending user info requests. |
| base::flat_set<std::unique_ptr<FederatedAuthUserInfoRequest>> |
| user_info_requests_; |
| |
| // Pending disconnect request. |
| std::unique_ptr<FederatedAuthDisconnectRequest> disconnect_request_; |
| |
| // TODO(crbug.com/40238075): Refactor these member variables introduced |
| // through the multi IDP prototype implementation to make them less confusing. |
| |
| // Parameters passed to RequestToken(). |
| base::flat_map<GURL, IdentityProviderGetInfo> token_request_get_infos_; |
| |
| // Data related to in-progress FetchEndpointsForIdps() fetch. |
| FetchData fetch_data_; |
| |
| // The set of IDPs that the user has tried to sign in to since the start of |
| // the current request. |
| base::flat_set<GURL> idps_user_tried_to_signin_to_; |
| |
| // List of config URLs of IDPs in the same order as the providers specified in |
| // the navigator.credentials.get call. |
| std::vector<GURL> idp_order_; |
| |
| // If dialog_type_ is kConfirmIdpLogin, this is the login URL for the IDP. If |
| // LoginToIdp() is called, this is the login URL for the IDP. Does not include |
| // the filters as query parameters, if any. |
| GURL login_url_; |
| |
| // If dialog_type_ is kError or a popup is open, this is the config URL for |
| // the IDP. |
| GURL config_url_; |
| |
| // If dialog_type_ is kError, this is the fetch status of the token request. |
| IdpNetworkRequestManager::FetchStatus token_request_status_; |
| |
| // If dialog_type_ is kError, this is the token error. |
| std::optional<TokenError> token_error_; |
| |
| DialogType dialog_type_ = kNone; |
| MediationRequirement mediation_requirement_; |
| IdentitySelectionType identity_selection_type_ = kExplicit; |
| RpMode rp_mode_{RpMode::kPassive}; |
| |
| // Time when the accounts dialog is last shown for metrics purposes. |
| std::optional<base::TimeTicks> accounts_dialog_shown_time_; |
| |
| // Time when the mismatch dialog is last shown for metrics purposes. |
| std::optional<base::TimeTicks> mismatch_dialog_shown_time_; |
| // Whether a mismatch dialog has been shown for the current request. |
| bool has_shown_mismatch_{false}; |
| |
| // Type of error URL for metrics and devtools issue purposes. |
| std::optional<IdpNetworkRequestManager::FedCmErrorUrlType> error_url_type_; |
| |
| // Number of navigator.credentials.get() requests made for metrics purposes. |
| // Requests made when there is a pending FedCM request or for the purpose of |
| // Wallets or multi-IDP are not counted. |
| int num_requests_{0}; |
| |
| // The active flow requires user activation to be kicked off. We'd also need |
| // this information along the way. e.g. showing pop-up window when accounts |
| // fetch is failed. However, the function `HasTransientUserActivation` may |
| // return false at that time because the network requests may be very slow |
| // such that the previous user gesture is expired. Therefore we store the |
| // information to use it during the entire the active flow. |
| bool had_transient_user_activation_{false}; |
| |
| // Whether we have shown any UI during this flow. |
| bool did_show_ui_{false}; |
| |
| // Keeps track of the state of the use other account flow. Is std::nullopt |
| // when the flow is not active. |
| std::optional<FedCmUseOtherAccountResult> use_other_account_account_result_; |
| |
| // Whether a token request has been sent. |
| bool has_sent_token_request_{false}; |
| |
| // Keeps track of the state of the verifying dialog. Is std::nullopt when the |
| // verifying dialog has not been shown. |
| std::optional<FedCmVerifyingDialogResult> verifying_dialog_result_; |
| |
| base::WeakPtrFactory<FederatedAuthRequestImpl> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_WEBID_FEDERATED_AUTH_REQUEST_IMPL_H_ |