blob: 2f511e98ca2f33a20359eb989dba56087a6a609f [file] [log] [blame]
// 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_PUBLIC_BROWSER_IDENTITY_REQUEST_DIALOG_CONTROLLER_H_
#define CONTENT_PUBLIC_BROWSER_IDENTITY_REQUEST_DIALOG_CONTROLLER_H_
#include <optional>
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/identity_request_account.h"
#include "third_party/blink/public/mojom/webid/federated_auth_request.mojom-forward.h"
#include "third_party/skia/include/core/SkColor.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
class WebContents;
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.webid
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: IdentityRequestDialogDisclosureField
enum class IdentityRequestDialogDisclosureField {
kName,
kEmail,
kPicture,
kPhoneNumber,
kUsername
};
// The client metadata that will be used to display a FedCM dialog. This data is
// extracted from the client metadata endpoint from the FedCM API, where
// 'client' is essentially the relying party which invoked the API.
struct CONTENT_EXPORT ClientMetadata {
ClientMetadata(const GURL& terms_of_service_url,
const GURL& privacy_policy_url,
const GURL& brand_icon_url,
const gfx::Image& brand_decoded_icon);
ClientMetadata(const ClientMetadata& other);
~ClientMetadata();
GURL terms_of_service_url;
GURL privacy_policy_url;
GURL brand_icon_url;
// This will be an empty image if the fetching never happened or if it failed.
gfx::Image brand_decoded_icon;
};
// The information about an error that will be used to display a FedCM dialog.
// This data is extracted from the error object returned by the identity
// provider when the user attempts to login via the FedCM API and an error
// occurs.
struct CONTENT_EXPORT IdentityCredentialTokenError {
std::string code;
GURL url;
};
// The metadata about the identity provider that will be used to display a FedCM
// dialog. This data is extracted from the config file which is fetched when the
// FedCM API is invoked.
struct CONTENT_EXPORT IdentityProviderMetadata {
IdentityProviderMetadata();
IdentityProviderMetadata(const IdentityProviderMetadata& other);
~IdentityProviderMetadata();
std::optional<SkColor> brand_text_color;
std::optional<SkColor> brand_background_color;
GURL brand_icon_url;
GURL idp_login_url;
std::string requested_label;
// For registered IdPs, the type is used to only show the accounts when the
// RP is compatible.
std::vector<std::string> types;
// The token formats that are supported.
std::vector<std::string> formats;
// The URL of the configuration endpoint. This is stored in
// IdentityProviderMetadata so that the UI code can pass it along when an
// Account is selected by the user.
GURL config_url;
// Whether this IdP supports signing in to additional accounts.
bool supports_add_account{false};
// Whether this IdP has any filtered out account. This is reset to false each
// time the accounts dialog is shown and recomputed then.
bool has_filtered_out_account{false};
// This will be an empty image if fetching failed.
gfx::Image brand_decoded_icon;
};
// This class contains all of the data specific to an identity provider that is
// going to be used to display a FedCM dialog. This data is gathered from
// endpoints fetched when the FedCM API is invoked as well as from the
// parameters provided by the relying party when the API is invoked.
class CONTENT_EXPORT IdentityProviderData
: public base::RefCounted<IdentityProviderData> {
public:
IdentityProviderData(const std::string& idp_for_display,
const IdentityProviderMetadata& idp_metadata,
const ClientMetadata& client_metadata,
blink::mojom::RpContext rp_context,
std::optional<blink::mojom::Format> format,
const std::vector<IdentityRequestDialogDisclosureField>&
disclosure_fields,
bool has_login_status_mismatch);
std::string idp_for_display;
IdentityProviderMetadata idp_metadata;
ClientMetadata client_metadata;
blink::mojom::RpContext rp_context;
std::optional<blink::mojom::Format> format;
// For which fields should the dialog request permission for (assuming
// this is for signup).
std::vector<IdentityRequestDialogDisclosureField> disclosure_fields;
// Whether there was some login status API mismatch when fetching the IDP's
// accounts.
bool has_login_status_mismatch;
private:
friend class base::RefCounted<IdentityProviderData>;
~IdentityProviderData();
};
// The relying party data that will be used to display a FedCM dialog. This data
// is extracted from the website which invoked the API, not from the FedCM
// endpoints themselves.
struct CONTENT_EXPORT RelyingPartyData {
public:
RelyingPartyData(const std::string& rp_for_display,
const std::string& iframe_for_display);
RelyingPartyData(const RelyingPartyData& other);
~RelyingPartyData();
std::string rp_for_display;
// The formatted iframe origin. Empty if the iframe is same-site with
// `rp_for_display`.
std::string iframe_for_display;
gfx::Image rp_icon;
};
// IdentityRequestDialogController is an interface, overridden and implemented
// by embedders, that controls the UI surfaces that are displayed to
// intermediate the exchange of federated accounts between identity providers
// and relying parties.
class CONTENT_EXPORT IdentityRequestDialogController {
public:
// This enum is used to back a histogram. Do not remove or reorder members.
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.webid
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: IdentityRequestDialogDismissReason
enum class DismissReason {
kOther = 0,
kCloseButton = 1,
// Android-specific
kSwipe = 2,
// Android-specific
kVirtualKeyboardShown = 3,
kGotItButton = 4,
kMoreDetailsButton = 5,
// Android-specific
kBackPress = 6,
// Android-specific
kTapScrim = 7,
kSuppressed = 8,
kMaxValue = kSuppressed,
};
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.webid
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: IdentityRequestDialogLinkType
enum class LinkType { PRIVACY_POLICY, TERMS_OF_SERVICE };
using AccountSelectionCallback =
base::OnceCallback<void(const GURL& idp_config_url,
const std::string& /*account_id*/,
bool /*is_sign_in*/)>;
using TokenCallback = base::OnceCallback<void(const std::string& /*token*/)>;
using DismissCallback =
base::OnceCallback<void(DismissReason dismiss_reason)>;
using LoginToIdPCallback =
base::RepeatingCallback<void(const GURL& /*idp_config_url*/,
GURL /*idp_login_url*/)>;
using MoreDetailsCallback = base::OnceCallback<void()>;
using AccountsDisplayedCallback = base::OnceCallback<void()>;
IdentityRequestDialogController() = default;
IdentityRequestDialogController(const IdentityRequestDialogController&) =
delete;
IdentityRequestDialogController& operator=(
const IdentityRequestDialogController&) = delete;
virtual ~IdentityRequestDialogController() = default;
// Returns the ideal size for the identity provider brand icon. The brand icon
// is displayed in the accounts dialog.
virtual int GetBrandIconIdealSize(blink::mojom::RpMode rp_mode);
// Returns the minimum size for the identity provider brand icon. The brand
// icon is displayed in the accounts dialog.
virtual int GetBrandIconMinimumSize(blink::mojom::RpMode rp_mode);
// When this is true, the dialog should not be immediately auto-accepted.
virtual void SetIsInterceptionEnabled(bool enabled);
// Shows and accounts selections for the given IDP. The `on_selected` callback
// is called with the selected account id or empty string otherwise.
// `sign_in_mode` represents whether this is an auto re-authn flow.
// `new_accounts` are the accounts that were just logged in, which should
// be prioritized in the UI. Returns true if the method successfully showed
// UI. When false, the caller should assume that the API invocation was
// terminated and the cleanup methods invoked. `rp_data` may be modified by
// this method, such as by setting the RP icon.
virtual bool ShowAccountsDialog(
RelyingPartyData rp_data,
const std::vector<scoped_refptr<IdentityProviderData>>& idp_list,
const std::vector<scoped_refptr<IdentityRequestAccount>>& accounts,
IdentityRequestAccount::SignInMode sign_in_mode,
blink::mojom::RpMode rp_mode,
const std::vector<scoped_refptr<IdentityRequestAccount>>& new_accounts,
AccountSelectionCallback on_selected,
LoginToIdPCallback on_add_account,
DismissCallback dismiss_callback,
AccountsDisplayedCallback accounts_displayed_callback);
// Shows a failure UI when the accounts fetch is failed such that it is
// observable by users. This could happen when an IDP claims that the user is
// signed in but not respond with any user account during browser fetches.
// Returns true if the method successfully showed UI. When false, the caller
// should assume that the API invocation was terminated and the cleanup
// methods invoked.
virtual bool ShowFailureDialog(const std::string& rp_for_display,
const std::string& idp_for_display,
blink::mojom::RpContext rp_context,
blink::mojom::RpMode rp_mode,
const IdentityProviderMetadata& idp_metadata,
DismissCallback dismiss_callback,
LoginToIdPCallback login_callback);
// Shows an error UI when the user's sign-in attempt failed. Returns true if
// the method successfully showed UI. When false, the caller should assume
// that the API invocation was terminated and the cleanup methods invoked.
virtual bool ShowErrorDialog(
const std::string& rp_for_display,
const std::string& idp_for_display,
blink::mojom::RpContext rp_context,
blink::mojom::RpMode rp_mode,
const IdentityProviderMetadata& idp_metadata,
const std::optional<IdentityCredentialTokenError>& error,
DismissCallback dismiss_callback,
MoreDetailsCallback more_details_callback);
// Shows a loading UI when the user triggers a button flow and while waiting
// for their accounts to be fetched. Returns true if the method successfully
// showed UI. When false, the caller should assume that the API invocation was
// terminated and the cleanup methods invoked.
virtual bool ShowLoadingDialog(const std::string& rp_for_display,
const std::string& idp_for_display,
blink::mojom::RpContext rp_context,
blink::mojom::RpMode rp_mode,
DismissCallback dismiss_callback);
// Only to be called after a dialog is shown.
virtual std::string GetTitle() const;
virtual std::optional<std::string> GetSubtitle() const;
// Open a popup or similar that shows the specified URL.
virtual void ShowUrl(LinkType type, const GURL& url);
// Show a modal dialog that loads content from the IdP.
virtual WebContents* ShowModalDialog(const GURL& url,
blink::mojom::RpMode rp_mode,
DismissCallback dismiss_callback);
// Closes the modal dialog.
virtual void CloseModalDialog();
// When called on an object corresponding to the popup opened by
// ShowModalDialog, returns the web contents for the original RP page.
virtual WebContents* GetRpWebContents();
// Request the user's permission to register an origin as an identity
// provider. Calls the callback with a response of whether the request was
// accepted or not.
virtual void RequestIdPRegistrationPermision(
const url::Origin& origin,
base::OnceCallback<void(bool accepted)> callback);
// Notifies when the autofill data source is ready to be queried.
virtual void NotifyAutofillSourceReadyForTesting();
protected:
bool is_interception_enabled_{false};
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_IDENTITY_REQUEST_DIALOG_CONTROLLER_H_