blob: 364f0ef3d527aff8e64408a9899f95ff629dc19f [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.
#include "chrome/browser/ui/webid/identity_dialog_controller.h"
#include <memory>
#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "chrome/browser/ui/webid/account_selection_view.h"
#include "chrome/browser/webid/identity_provider_permission_request.h"
#include "components/permissions/permission_request_manager.h"
IdentityDialogController::IdentityDialogController(
content::WebContents* rp_web_contents)
: rp_web_contents_(rp_web_contents) {}
IdentityDialogController::~IdentityDialogController() = default;
int IdentityDialogController::GetBrandIconMinimumSize() {
return AccountSelectionView::GetBrandIconMinimumSize();
}
int IdentityDialogController::GetBrandIconIdealSize() {
return AccountSelectionView::GetBrandIconIdealSize();
}
void IdentityDialogController::ShowAccountsDialog(
const std::string& top_frame_for_display,
const std::optional<std::string>& iframe_for_display,
const std::vector<content::IdentityProviderData>& identity_provider_data,
content::IdentityRequestAccount::SignInMode sign_in_mode,
blink::mojom::RpMode rp_mode,
const std::optional<content::IdentityProviderData>& new_account_idp,
AccountSelectionCallback on_selected,
LoginToIdPCallback on_add_account,
DismissCallback dismiss_callback,
AccountsDisplayedCallback accounts_displayed_callback) {
on_account_selection_ = std::move(on_selected);
on_login_ = std::move(on_add_account);
on_dismiss_ = std::move(dismiss_callback);
on_accounts_displayed_ = std::move(accounts_displayed_callback);
if (!account_view_)
account_view_ = AccountSelectionView::Create(this);
account_view_->Show(top_frame_for_display, iframe_for_display,
identity_provider_data, sign_in_mode, rp_mode,
new_account_idp);
}
void IdentityDialogController::ShowFailureDialog(
const std::string& top_frame_for_display,
const std::optional<std::string>& iframe_for_display,
const std::string& idp_for_display,
blink::mojom::RpContext rp_context,
blink::mojom::RpMode rp_mode,
const content::IdentityProviderMetadata& idp_metadata,
DismissCallback dismiss_callback,
LoginToIdPCallback login_callback) {
const GURL rp_url = rp_web_contents_->GetLastCommittedURL();
on_dismiss_ = std::move(dismiss_callback);
on_login_ = std::move(login_callback);
if (!account_view_)
account_view_ = AccountSelectionView::Create(this);
// Else:
// TODO: If the failure dialog is already being shown, notify user that
// sign-in attempt failed.
account_view_->ShowFailureDialog(top_frame_for_display, iframe_for_display,
idp_for_display, rp_context, rp_mode,
idp_metadata);
}
void IdentityDialogController::ShowErrorDialog(
const std::string& top_frame_for_display,
const std::optional<std::string>& iframe_for_display,
const std::string& idp_for_display,
blink::mojom::RpContext rp_context,
blink::mojom::RpMode rp_mode,
const content::IdentityProviderMetadata& idp_metadata,
const std::optional<TokenError>& error,
DismissCallback dismiss_callback,
MoreDetailsCallback more_details_callback) {
on_dismiss_ = std::move(dismiss_callback);
on_more_details_ = std::move(more_details_callback);
if (!account_view_) {
account_view_ = AccountSelectionView::Create(this);
}
account_view_->ShowErrorDialog(top_frame_for_display, iframe_for_display,
idp_for_display, rp_context, rp_mode,
idp_metadata, error);
}
void IdentityDialogController::ShowLoadingDialog(
const std::string& top_frame_for_display,
const std::string& idp_for_display,
blink::mojom::RpContext rp_context,
blink::mojom::RpMode rp_mode,
DismissCallback dismiss_callback) {
on_dismiss_ = std::move(dismiss_callback);
if (!account_view_) {
account_view_ = AccountSelectionView::Create(this);
}
account_view_->ShowLoadingDialog(top_frame_for_display, idp_for_display,
rp_context, rp_mode);
}
void IdentityDialogController::OnLoginToIdP(const GURL& idp_config_url,
const GURL& idp_login_url) {
CHECK(on_login_);
std::move(on_login_).Run(idp_config_url, idp_login_url);
}
void IdentityDialogController::OnMoreDetails() {
CHECK(on_more_details_);
std::move(on_more_details_).Run();
}
void IdentityDialogController::OnAccountsDisplayed() {
CHECK(on_accounts_displayed_);
std::move(on_accounts_displayed_).Run();
}
void IdentityDialogController::OnAccountSelected(const GURL& idp_config_url,
const Account& account) {
CHECK(on_account_selection_);
on_dismiss_.Reset();
std::move(on_account_selection_)
.Run(idp_config_url, account.id,
account.login_state ==
content::IdentityRequestAccount::LoginState::kSignIn);
}
void IdentityDialogController::OnDismiss(DismissReason dismiss_reason) {
// |OnDismiss| can be called after |OnAccountSelected| which sets the callback
// to null.
if (!on_dismiss_) {
return;
}
on_account_selection_.Reset();
std::move(on_dismiss_).Run(dismiss_reason);
}
std::string IdentityDialogController::GetTitle() const {
return account_view_->GetTitle();
}
std::optional<std::string> IdentityDialogController::GetSubtitle() const {
return account_view_->GetSubtitle();
}
gfx::NativeView IdentityDialogController::GetNativeView() {
return rp_web_contents_->GetNativeView();
}
content::WebContents* IdentityDialogController::GetWebContents() {
return rp_web_contents_;
}
void IdentityDialogController::ShowUrl(LinkType type, const GURL& url) {
if (!account_view_) {
return;
}
account_view_->ShowUrl(type, url);
}
content::WebContents* IdentityDialogController::ShowModalDialog(
const GURL& url,
DismissCallback dismiss_callback) {
on_dismiss_ = std::move(dismiss_callback);
if (!account_view_) {
account_view_ = AccountSelectionView::Create(this);
}
return account_view_->ShowModalDialog(url);
}
void IdentityDialogController::CloseModalDialog() {
#if BUILDFLAG(IS_ANDROID)
// On Android, this method is invoked on the modal dialog controller,
// which means we may need to initialize the |account_view|.
if (!account_view_) {
account_view_ = AccountSelectionView::Create(this);
}
#endif // BUILDFLAG(IS_ANDROID)
CHECK(account_view_);
account_view_->CloseModalDialog();
}
void IdentityDialogController::RequestIdPRegistrationPermision(
const url::Origin& origin,
base::OnceCallback<void(bool accepted)> callback) {
permissions::PermissionRequestManager* permission_request_manager =
permissions::PermissionRequestManager::FromWebContents(rp_web_contents_);
auto* request =
new IdentityProviderPermissionRequest(origin, std::move(callback));
permission_request_manager->AddRequest(
rp_web_contents_->GetPrimaryMainFrame(), request);
}