Commit 7d68835d authored by Ken Buchanan's avatar Ken Buchanan Committed by Chromium LUCI CQ

[WebID] Add stubs for calls to WebID permission UI dialogs

This adds plumbing to WebID federation requests to generate dialogs
for user permission and IDP sign-in. The prototype dialog
implementations will be added later.

Bug: 1141125
Change-Id: I37d26d8d376482c3e285907bd3eb0f56b450613b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2569379
Commit-Queue: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833999}
parent e17fb2c4
...@@ -159,6 +159,7 @@ ...@@ -159,6 +159,7 @@
#include "chrome/browser/ui/sync/sync_promo_ui.h" #include "chrome/browser/ui/sync/sync_promo_ui.h"
#include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h" #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webid/identity_dialog_controller.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/browser/ui/webui/log_web_ui_url.h" #include "chrome/browser/ui/webui/log_web_ui_url.h"
#include "chrome/browser/usb/frame_usb_services.h" #include "chrome/browser/usb/frame_usb_services.h"
...@@ -5933,6 +5934,11 @@ bool ChromeContentBrowserClient::HasErrorPage(int http_status_code) { ...@@ -5933,6 +5934,11 @@ bool ChromeContentBrowserClient::HasErrorPage(int http_status_code) {
error_page::Error::kHttpErrorDomain, http_status_code); error_page::Error::kHttpErrorDomain, http_status_code);
} }
std::unique_ptr<content::IdentityRequestDialogController>
ChromeContentBrowserClient::CreateIdentityRequestDialogController() {
return std::make_unique<IdentityDialogController>();
}
void ChromeContentBrowserClient::OnKeepaliveTimerFired( void ChromeContentBrowserClient::OnKeepaliveTimerFired(
std::unique_ptr<ScopedKeepAlive> keep_alive_handle) { std::unique_ptr<ScopedKeepAlive> keep_alive_handle) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
......
...@@ -720,6 +720,9 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { ...@@ -720,6 +720,9 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
StartupData* startup_data() { return &startup_data_; } StartupData* startup_data() { return &startup_data_; }
std::unique_ptr<content::IdentityRequestDialogController>
CreateIdentityRequestDialogController() override;
protected: protected:
static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context); static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context);
static bool HandleWebUIReverse(GURL* url, static bool HandleWebUIReverse(GURL* url,
......
...@@ -185,6 +185,8 @@ static_library("ui") { ...@@ -185,6 +185,8 @@ static_library("ui") {
"uninstall_browser_prompt.h", "uninstall_browser_prompt.h",
"view_ids.h", "view_ids.h",
"webauthn/authenticator_request_dialog.h", "webauthn/authenticator_request_dialog.h",
"webid/identity_dialog_controller.cc",
"webid/identity_dialog_controller.h",
"webui/about_ui.cc", "webui/about_ui.cc",
"webui/about_ui.h", "webui/about_ui.h",
"webui/autofill_and_password_manager_internals/autofill_internals_ui.cc", "webui/autofill_and_password_manager_internals/autofill_internals_ui.cc",
......
monorail {
component: "Blink>Identity>WebID"
}
file://content/browser/webid/OWNERS
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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 "url/gurl.h"
IdentityDialogController::IdentityDialogController() = default;
IdentityDialogController::~IdentityDialogController() = default;
void IdentityDialogController::ShowInitialPermissionDialog(
InitialApprovalCallback callback) {
// TODO(kenrb): Add UI permission dialog.
std::move(callback).Run(
content::IdentityRequestDialogController::UserApproval::kApproved);
}
void IdentityDialogController::ShowIdProviderWindow(
const GURL& idp_signin_url,
IdProviderWindowClosedCallback callback) {
// TODO(kenrb): Add UI modal window to display the IDP UI and load the IDP
// page.
std::move(callback).Run();
}
void IdentityDialogController::ShowTokenExchangePermissionDialog(
TokenExchangeApprovalCallback callback) {
// TODO(kenrb): Add Identity permission dialog.
std::move(callback).Run(
content::IdentityRequestDialogController::UserApproval::kApproved);
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBID_IDENTITY_DIALOG_CONTROLLER_H_
#define CHROME_BROWSER_UI_WEBID_IDENTITY_DIALOG_CONTROLLER_H_
#include "base/callback.h"
#include "content/public/browser/identity_request_dialog_controller.h"
class GURL;
using InitialApprovalCallback =
content::IdentityRequestDialogController::InitialApprovalCallback;
using IdProviderWindowClosedCallback =
content::IdentityRequestDialogController::IdProviderWindowClosedCallback;
using TokenExchangeApprovalCallback =
content::IdentityRequestDialogController::TokenExchangeApprovalCallback;
// The IdentityDialogController controls the views that are used across
// browser-mediated federated sign-in flows.
class IdentityDialogController
: public content::IdentityRequestDialogController {
public:
IdentityDialogController();
IdentityDialogController(const IdentityDialogController&) = delete;
IdentityDialogController& operator=(const IdentityDialogController&) = delete;
~IdentityDialogController() override;
// content::IdentityRequestDelegate
void ShowInitialPermissionDialog(InitialApprovalCallback) override;
void ShowIdProviderWindow(const GURL& idp_signin_url,
IdProviderWindowClosedCallback) override;
void ShowTokenExchangePermissionDialog(
TokenExchangeApprovalCallback) override;
};
#endif // CHROME_BROWSER_UI_WEBID_IDENTITY_DIALOG_CONTROLLER_H_
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/common/content_client.h"
#include "url/url_constants.h" #include "url/url_constants.h"
using blink::mojom::RequestIdTokenStatus; using blink::mojom::RequestIdTokenStatus;
...@@ -87,10 +88,13 @@ void FederatedAuthRequestImpl::RequestIdToken(const GURL& provider, ...@@ -87,10 +88,13 @@ void FederatedAuthRequestImpl::RequestIdToken(const GURL& provider,
network_manager_ = network_manager_ =
IdpNetworkRequestManager::Create(provider, render_frame_host()); IdpNetworkRequestManager::Create(provider, render_frame_host());
if (!network_manager_) { if (!network_manager_) {
std::move(callback_).Run(RequestIdTokenStatus::kError, ""); CompleteRequest(RequestIdTokenStatus::kError, "");
return; return;
} }
request_dialog_controller_ =
GetContentClient()->browser()->CreateIdentityRequestDialogController();
network_manager_->FetchIDPWellKnown( network_manager_->FetchIDPWellKnown(
base::BindOnce(&FederatedAuthRequestImpl::OnWellKnownFetched, base::BindOnce(&FederatedAuthRequestImpl::OnWellKnownFetched,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
...@@ -101,12 +105,12 @@ void FederatedAuthRequestImpl::OnWellKnownFetched( ...@@ -101,12 +105,12 @@ void FederatedAuthRequestImpl::OnWellKnownFetched(
const std::string& idp_endpoint) { const std::string& idp_endpoint) {
switch (status) { switch (status) {
case IdpNetworkRequestManager::FetchStatus::kWebIdNotSupported: { case IdpNetworkRequestManager::FetchStatus::kWebIdNotSupported: {
std::move(callback_).Run( CompleteRequest(RequestIdTokenStatus::kErrorWebIdNotSupportedByProvider,
RequestIdTokenStatus::kErrorWebIdNotSupportedByProvider, ""); "");
return; return;
} }
case IdpNetworkRequestManager::FetchStatus::kFetchError: { case IdpNetworkRequestManager::FetchStatus::kFetchError: {
std::move(callback_).Run(RequestIdTokenStatus::kError, ""); CompleteRequest(RequestIdTokenStatus::kError, "");
return; return;
} }
case IdpNetworkRequestManager::FetchStatus::kSuccess: { case IdpNetworkRequestManager::FetchStatus::kSuccess: {
...@@ -119,18 +123,19 @@ void FederatedAuthRequestImpl::OnWellKnownFetched( ...@@ -119,18 +123,19 @@ void FederatedAuthRequestImpl::OnWellKnownFetched(
// provider, or is that not a requirement? // provider, or is that not a requirement?
// https://crbug.com/1141125 // https://crbug.com/1141125
if (!IdpUrlIsValid(idp_endpoint_url_)) { if (!IdpUrlIsValid(idp_endpoint_url_)) {
std::move(callback_).Run(RequestIdTokenStatus::kError, ""); CompleteRequest(RequestIdTokenStatus::kError, "");
return; return;
} }
// TODO(kenrb): Call out to the consent UI with OnSigninApproved as a request_dialog_controller_->ShowInitialPermissionDialog(
// callback. https://crbug.com/1141125. base::BindOnce(&FederatedAuthRequestImpl::OnSigninApproved,
OnSigninApproved(true); weak_ptr_factory_.GetWeakPtr()));
} }
void FederatedAuthRequestImpl::OnSigninApproved(bool approval_granted) { void FederatedAuthRequestImpl::OnSigninApproved(
if (!approval_granted) { IdentityRequestDialogController::UserApproval approval) {
std::move(callback_).Run(RequestIdTokenStatus::kApprovalDeclined, ""); if (approval != IdentityRequestDialogController::UserApproval::kApproved) {
CompleteRequest(RequestIdTokenStatus::kApprovalDeclined, "");
return; return;
} }
...@@ -149,23 +154,54 @@ void FederatedAuthRequestImpl::OnSigninResponseReceived( ...@@ -149,23 +154,54 @@ void FederatedAuthRequestImpl::OnSigninResponseReceived(
case IdpNetworkRequestManager::SigninResponse::kLoadIdp: { case IdpNetworkRequestManager::SigninResponse::kLoadIdp: {
GURL idp_signin_page_url = GURL(base::StringPiece(response)); GURL idp_signin_page_url = GURL(base::StringPiece(response));
if (!IdpUrlIsValid(idp_signin_page_url)) { if (!IdpUrlIsValid(idp_signin_page_url)) {
std::move(callback_).Run(RequestIdTokenStatus::kError, ""); CompleteRequest(RequestIdTokenStatus::kError, "");
return; return;
} }
} request_dialog_controller_->ShowIdProviderWindow(
// TODO(kenrb): Create window and load IDP URL. For now just return idp_signin_page_url,
// success. https://crbug.com/1141125. base::BindOnce(&FederatedAuthRequestImpl::OnIdpPageClosed,
std::move(callback_).Run(RequestIdTokenStatus::kSuccess, ""); weak_ptr_factory_.GetWeakPtr()));
return; return;
}
case IdpNetworkRequestManager::SigninResponse::kTokenGranted: { case IdpNetworkRequestManager::SigninResponse::kTokenGranted: {
std::move(callback_).Run(RequestIdTokenStatus::kSuccess, response); // TODO(kenrb): Returning success here has to be dependent on whether
// a WebID flow has succeeded in the past, otherwise jump to
// the token permission dialog.
CompleteRequest(RequestIdTokenStatus::kSuccess, response);
return; return;
} }
case IdpNetworkRequestManager::SigninResponse::kSigninError: { case IdpNetworkRequestManager::SigninResponse::kSigninError: {
std::move(callback_).Run(RequestIdTokenStatus::kError, ""); CompleteRequest(RequestIdTokenStatus::kError, "");
return; return;
} }
} }
} }
void FederatedAuthRequestImpl::OnIdpPageClosed() {
// TODO(kenrb): This needs to take a token that was provided by the IDP,
// or have an abort path if none provided.
request_dialog_controller_->ShowTokenExchangePermissionDialog(
base::BindOnce(&FederatedAuthRequestImpl::OnTokenProvisionApproved,
weak_ptr_factory_.GetWeakPtr()));
}
void FederatedAuthRequestImpl::OnTokenProvisionApproved(
IdentityRequestDialogController::UserApproval approval) {
if (approval != IdentityRequestDialogController::UserApproval::kApproved) {
CompleteRequest(RequestIdTokenStatus::kApprovalDeclined, "");
return;
}
// TODO(kenrb): Token gets returned here.
CompleteRequest(RequestIdTokenStatus::kSuccess, "");
}
void FederatedAuthRequestImpl::CompleteRequest(
blink::mojom::RequestIdTokenStatus status,
const std::string& id_token) {
request_dialog_controller_.reset();
network_manager_.reset();
std::move(callback_).Run(status, id_token);
}
} // namespace content } // namespace content
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "content/browser/webid/idp_network_request_manager.h" #include "content/browser/webid/idp_network_request_manager.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/browser/frame_service_base.h" #include "content/public/browser/frame_service_base.h"
#include "content/public/browser/identity_request_dialog_controller.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h" #include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -35,11 +36,11 @@ class CONTENT_EXPORT FederatedAuthRequestImpl ...@@ -35,11 +36,11 @@ class CONTENT_EXPORT FederatedAuthRequestImpl
static void Create(RenderFrameHost*, static void Create(RenderFrameHost*,
mojo::PendingReceiver<blink::mojom::FederatedAuthRequest>); mojo::PendingReceiver<blink::mojom::FederatedAuthRequest>);
~FederatedAuthRequestImpl() override;
FederatedAuthRequestImpl(const FederatedAuthRequestImpl&) = delete; FederatedAuthRequestImpl(const FederatedAuthRequestImpl&) = delete;
FederatedAuthRequestImpl& operator=(const FederatedAuthRequestImpl&) = delete; FederatedAuthRequestImpl& operator=(const FederatedAuthRequestImpl&) = delete;
~FederatedAuthRequestImpl() override;
// blink::mojom::FederatedAuthRequest: // blink::mojom::FederatedAuthRequest:
void RequestIdToken(const GURL& provider, void RequestIdToken(const GURL& provider,
const std::string& id_request, const std::string& id_request,
...@@ -52,11 +53,19 @@ class CONTENT_EXPORT FederatedAuthRequestImpl ...@@ -52,11 +53,19 @@ class CONTENT_EXPORT FederatedAuthRequestImpl
void OnWellKnownFetched(IdpNetworkRequestManager::FetchStatus status, void OnWellKnownFetched(IdpNetworkRequestManager::FetchStatus status,
const std::string& idp_endpoint); const std::string& idp_endpoint);
void OnSigninApproved(bool approval_granted);
void OnSigninApproved(IdentityRequestDialogController::UserApproval approval);
void OnSigninResponseReceived(IdpNetworkRequestManager::SigninResponse status, void OnSigninResponseReceived(IdpNetworkRequestManager::SigninResponse status,
const std::string& response); const std::string& response);
void OnIdpPageClosed();
void OnTokenProvisionApproved(
IdentityRequestDialogController::UserApproval approval);
void CompleteRequest(blink::mojom::RequestIdTokenStatus,
const std::string& id_token);
std::unique_ptr<IdpNetworkRequestManager> network_manager_; std::unique_ptr<IdpNetworkRequestManager> network_manager_;
std::unique_ptr<IdentityRequestDialogController> request_dialog_controller_;
// Parameters of auth request. // Parameters of auth request.
GURL provider_; GURL provider_;
......
...@@ -187,7 +187,7 @@ void IdpNetworkRequestManager::SendSigninRequest( ...@@ -187,7 +187,7 @@ void IdpNetworkRequestManager::SendSigninRequest(
void IdpNetworkRequestManager::OnWellKnownLoaded( void IdpNetworkRequestManager::OnWellKnownLoaded(
std::unique_ptr<std::string> response_body) { std::unique_ptr<std::string> response_body) {
url_loader_.reset(nullptr); url_loader_.reset();
int response_code = -1; int response_code = -1;
if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers)
...@@ -245,7 +245,7 @@ void IdpNetworkRequestManager::OnSigninRequestResponse( ...@@ -245,7 +245,7 @@ void IdpNetworkRequestManager::OnSigninRequestResponse(
if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers)
response_code = url_loader_->ResponseInfo()->headers->response_code(); response_code = url_loader_->ResponseInfo()->headers->response_code();
url_loader_.reset(nullptr); url_loader_.reset();
if (!response_body) { if (!response_body) {
std::move(signin_request_callback_) std::move(signin_request_callback_)
......
...@@ -180,6 +180,7 @@ source_set("browser_sources") { ...@@ -180,6 +180,7 @@ source_set("browser_sources") {
"hid_chooser.h", "hid_chooser.h",
"hid_delegate.h", "hid_delegate.h",
"histogram_fetcher.h", "histogram_fetcher.h",
"identity_request_dialog_controller.h",
"idle_manager.h", "idle_manager.h",
"installability_error.cc", "installability_error.cc",
"installability_error.h", "installability_error.h",
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_main_parts.h" #include "content/public/browser/browser_main_parts.h"
#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/identity_request_dialog_controller.h"
#include "content/public/browser/login_delegate.h" #include "content/public/browser/login_delegate.h"
#include "content/public/browser/navigation_throttle.h" #include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/navigation_ui_data.h"
...@@ -1145,4 +1146,9 @@ bool ContentBrowserClient::HasErrorPage(int http_status_code) { ...@@ -1145,4 +1146,9 @@ bool ContentBrowserClient::HasErrorPage(int http_status_code) {
return false; return false;
} }
std::unique_ptr<IdentityRequestDialogController>
ContentBrowserClient::CreateIdentityRequestDialogController() {
return nullptr;
}
} // namespace content } // namespace content
...@@ -192,6 +192,7 @@ class DevToolsManagerDelegate; ...@@ -192,6 +192,7 @@ class DevToolsManagerDelegate;
class FeatureObserverClient; class FeatureObserverClient;
class FontAccessDelegate; class FontAccessDelegate;
class HidDelegate; class HidDelegate;
class IdentityRequestDialogController;
class LoginDelegate; class LoginDelegate;
class MediaObserver; class MediaObserver;
class NavigationHandle; class NavigationHandle;
...@@ -1903,6 +1904,10 @@ class CONTENT_EXPORT ContentBrowserClient { ...@@ -1903,6 +1904,10 @@ class CONTENT_EXPORT ContentBrowserClient {
// Returns true if the embedder has an error page to show for the given http // Returns true if the embedder has an error page to show for the given http
// status code. // status code.
virtual bool HasErrorPage(int http_status_code); virtual bool HasErrorPage(int http_status_code);
// Creates a modal window that intermediates the exchange of ID tokens.
virtual std::unique_ptr<IdentityRequestDialogController>
CreateIdentityRequestDialogController();
}; };
} // namespace content } // namespace content
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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 "base/callback.h"
#include "content/common/content_export.h"
class GURL;
namespace content {
// IdentityRequestDialogController is in interface for control of the UI
// surfaces that are displayed to intermediate the exchange of ID tokens.
class CONTENT_EXPORT IdentityRequestDialogController {
public:
enum class UserApproval {
kApproved,
kDenied,
};
using InitialApprovalCallback = base::OnceCallback<void(UserApproval)>;
using IdProviderWindowClosedCallback = base::OnceCallback<void()>;
using TokenExchangeApprovalCallback = base::OnceCallback<void(UserApproval)>;
IdentityRequestDialogController() = default;
IdentityRequestDialogController(const IdentityRequestDialogController&) =
delete;
IdentityRequestDialogController& operator=(
const IdentityRequestDialogController&) = delete;
virtual ~IdentityRequestDialogController() = default;
// Permission-oriented flow methods.
virtual void ShowInitialPermissionDialog(InitialApprovalCallback) = 0;
virtual void ShowIdProviderWindow(const GURL& idp_signin_url,
IdProviderWindowClosedCallback) = 0;
virtual void ShowTokenExchangePermissionDialog(
TokenExchangeApprovalCallback) = 0;
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_IDENTITY_REQUEST_DIALOG_CONTROLLER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment