Commit c02342fb authored by John Abd-El-Malek's avatar John Abd-El-Malek Committed by Commit Bot

Fix ForceBrowserSignIn not working with networking service.

The problem was that the old sign-in flow didn't work with networking service. This hasn't been converted to use DICE, which already works.

There were two causes:
-webRequest interception wasn't enabled for the few internal webui pages that are whitelisted for webRequest API
-webRequest users don't see Set-Cookie headers for responses (since these were sent to the interceptor from the network process, and the IPC serialization removes Cookie headers)

Bug: 887381
Change-Id: I4f0b598c1610cd3b11dcf01cdd4d43425f218a4f
Reviewed-on: https://chromium-review.googlesource.com/1238720Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarClark DuVall <cduvall@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593703}
parent 5f4298e4
...@@ -153,7 +153,50 @@ void InlineLoginHandler::ContinueHandleInitializeMessage() { ...@@ -153,7 +153,50 @@ void InlineLoginHandler::ContinueHandleInitializeMessage() {
void InlineLoginHandler::HandleCompleteLoginMessage( void InlineLoginHandler::HandleCompleteLoginMessage(
const base::ListValue* args) { const base::ListValue* args) {
CompleteLogin(args); // When the network service is enabled, the webRequest API doesn't expose
// cookie headers. So manually fetch the cookies for the GAIA URL from the
// CookieManager.
content::WebContents* contents = web_ui()->GetWebContents();
content::StoragePartition* partition =
content::BrowserContext::GetStoragePartitionForSite(
contents->GetBrowserContext(), signin::GetSigninPartitionURL());
net::CookieOptions cookie_options;
cookie_options.set_include_httponly();
partition->GetCookieManagerForBrowserProcess()->GetCookieList(
GaiaUrls::GetInstance()->gaia_url(), cookie_options,
base::BindOnce(&InlineLoginHandler::HandleCompleteLoginMessageWithCookies,
weak_ptr_factory_.GetWeakPtr(),
base::ListValue(args->GetList())));
}
void InlineLoginHandler::HandleCompleteLoginMessageWithCookies(
const base::ListValue& args,
const std::vector<net::CanonicalCookie>& cookies) {
const base::DictionaryValue* dict = nullptr;
args.GetDictionary(0, &dict);
const std::string& email = dict->FindKey("email")->GetString();
const std::string& password = dict->FindKey("password")->GetString();
const std::string& gaia_id = dict->FindKey("gaiaId")->GetString();
std::string auth_code;
for (const auto& cookie : cookies) {
if (cookie.Name() == "oauth_code")
auth_code = cookie.Value();
}
bool skip_for_now = false;
dict->GetBoolean("skipForNow", &skip_for_now);
bool trusted = false;
bool trusted_found = dict->GetBoolean("trusted", &trusted);
bool choose_what_to_sync = false;
dict->GetBoolean("chooseWhatToSync", &choose_what_to_sync);
CompleteLogin(email, password, gaia_id, auth_code, skip_for_now, trusted,
trusted_found, choose_what_to_sync);
} }
void InlineLoginHandler::HandleSwitchToFullTabMessage( void InlineLoginHandler::HandleSwitchToFullTabMessage(
......
...@@ -13,6 +13,10 @@ namespace base { ...@@ -13,6 +13,10 @@ namespace base {
class DictionaryValue; class DictionaryValue;
} }
namespace net {
class CanonicalCookie;
}
namespace signin_metrics { namespace signin_metrics {
enum class AccessPoint; enum class AccessPoint;
} }
...@@ -54,6 +58,12 @@ class InlineLoginHandler : public content::WebUIMessageHandler { ...@@ -54,6 +58,12 @@ class InlineLoginHandler : public content::WebUIMessageHandler {
// work. // work.
void HandleCompleteLoginMessage(const base::ListValue* args); void HandleCompleteLoginMessage(const base::ListValue* args);
// Called by HandleCompleteLoginMessage after it gets the GAIA URL's cookies
// from the CookieManager.
void HandleCompleteLoginMessageWithCookies(
const base::ListValue& args,
const std::vector<net::CanonicalCookie>& cookies);
// JS callback to switch the UI from a constrainted dialog to a full tab. // JS callback to switch the UI from a constrainted dialog to a full tab.
void HandleSwitchToFullTabMessage(const base::ListValue* args); void HandleSwitchToFullTabMessage(const base::ListValue* args);
...@@ -65,7 +75,14 @@ class InlineLoginHandler : public content::WebUIMessageHandler { ...@@ -65,7 +75,14 @@ class InlineLoginHandler : public content::WebUIMessageHandler {
void HandleDialogClose(const base::ListValue* args); void HandleDialogClose(const base::ListValue* args);
virtual void SetExtraInitParams(base::DictionaryValue& params) {} virtual void SetExtraInitParams(base::DictionaryValue& params) {}
virtual void CompleteLogin(const base::ListValue* args) = 0; virtual void CompleteLogin(const std::string& email,
const std::string& password,
const std::string& gaia_id,
const std::string& auth_code,
bool skip_for_now,
bool trusted,
bool trusted_found,
bool choose_what_to_sync) = 0;
base::WeakPtrFactory<InlineLoginHandler> weak_ptr_factory_; base::WeakPtrFactory<InlineLoginHandler> weak_ptr_factory_;
......
...@@ -118,15 +118,16 @@ void InlineLoginHandlerChromeOS::SetExtraInitParams( ...@@ -118,15 +118,16 @@ void InlineLoginHandlerChromeOS::SetExtraInitParams(
params.SetKey("flow", base::Value("addaccount")); params.SetKey("flow", base::Value("addaccount"));
} }
void InlineLoginHandlerChromeOS::CompleteLogin(const base::ListValue* args) { void InlineLoginHandlerChromeOS::CompleteLogin(const std::string& email,
const base::DictionaryValue* auth_data = nullptr; const std::string& password,
CHECK(args->GetDictionary(0, &auth_data)); const std::string& gaia_id,
const std::string& auth_code,
const std::string& auth_code = auth_data->FindKey("authCode")->GetString(); bool skip_for_now,
bool trusted,
bool trusted_found,
bool choose_what_to_sync) {
CHECK(!auth_code.empty()); CHECK(!auth_code.empty());
const std::string& gaia_id = auth_data->FindKey("gaiaId")->GetString();
CHECK(!gaia_id.empty()); CHECK(!gaia_id.empty());
const std::string& email = auth_data->FindKey("email")->GetString();
CHECK(!email.empty()); CHECK(!email.empty());
// TODO(sinhak): Do not depend on Profile unnecessarily. // TODO(sinhak): Do not depend on Profile unnecessarily.
......
...@@ -21,7 +21,14 @@ class InlineLoginHandlerChromeOS : public InlineLoginHandler { ...@@ -21,7 +21,14 @@ class InlineLoginHandlerChromeOS : public InlineLoginHandler {
// InlineLoginHandler overrides. // InlineLoginHandler overrides.
void SetExtraInitParams(base::DictionaryValue& params) override; void SetExtraInitParams(base::DictionaryValue& params) override;
void CompleteLogin(const base::ListValue* args) override; void CompleteLogin(const std::string& email,
const std::string& password,
const std::string& gaia_id,
const std::string& auth_code,
bool skip_for_now,
bool trusted,
bool trusted_found,
bool choose_what_to_sync) override;
private: private:
base::RepeatingClosure close_dialog_closure_; base::RepeatingClosure close_dialog_closure_;
......
...@@ -484,15 +484,17 @@ void InlineLoginHandlerImpl::SetExtraInitParams(base::DictionaryValue& params) { ...@@ -484,15 +484,17 @@ void InlineLoginHandlerImpl::SetExtraInitParams(base::DictionaryValue& params) {
LogHistogramValue(signin_metrics::HISTOGRAM_SHOWN); LogHistogramValue(signin_metrics::HISTOGRAM_SHOWN);
} }
void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) { void InlineLoginHandlerImpl::CompleteLogin(const std::string& email,
const std::string& password,
const std::string& gaia_id,
const std::string& auth_code,
bool skip_for_now,
bool trusted,
bool trusted_found,
bool choose_what_to_sync) {
content::WebContents* contents = web_ui()->GetWebContents(); content::WebContents* contents = web_ui()->GetWebContents();
const GURL& current_url = contents->GetURL(); const GURL& current_url = contents->GetURL();
const base::DictionaryValue* dict = NULL;
args->GetDictionary(0, &dict);
bool skip_for_now = false;
dict->GetBoolean("skipForNow", &skip_for_now);
if (skip_for_now) { if (skip_for_now) {
signin::SetUserSkippedPromo(Profile::FromWebUI(web_ui())); signin::SetUserSkippedPromo(Profile::FromWebUI(web_ui()));
SyncStarterCallback(OneClickSigninSyncStarter::SYNC_SETUP_FAILURE); SyncStarterCallback(OneClickSigninSyncStarter::SYNC_SETUP_FAILURE);
...@@ -500,32 +502,13 @@ void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) { ...@@ -500,32 +502,13 @@ void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) {
} }
// This value exists only for webview sign in. // This value exists only for webview sign in.
bool trusted = false; if (trusted_found)
if (dict->GetBoolean("trusted", &trusted))
confirm_untrusted_signin_ = !trusted; confirm_untrusted_signin_ = !trusted;
base::string16 email_string16; DCHECK(!email.empty());
dict->GetString("email", &email_string16); DCHECK(!gaia_id.empty());
DCHECK(!email_string16.empty());
std::string email(base::UTF16ToASCII(email_string16));
base::string16 password_string16;
dict->GetString("password", &password_string16);
std::string password(base::UTF16ToASCII(password_string16));
base::string16 gaia_id_string16;
dict->GetString("gaiaId", &gaia_id_string16);
DCHECK(!gaia_id_string16.empty());
std::string gaia_id = base::UTF16ToASCII(gaia_id_string16);
base::string16 auth_code_string16;
dict->GetString("authCode", &auth_code_string16);
std::string auth_code = base::UTF16ToASCII(auth_code_string16);
DCHECK(!auth_code.empty()); DCHECK(!auth_code.empty());
bool choose_what_to_sync = false;
dict->GetBoolean("chooseWhatToSync", &choose_what_to_sync);
content::StoragePartition* partition = content::StoragePartition* partition =
content::BrowserContext::GetStoragePartitionForSite( content::BrowserContext::GetStoragePartitionForSite(
contents->GetBrowserContext(), signin::GetSigninPartitionURL()); contents->GetBrowserContext(), signin::GetSigninPartitionURL());
......
...@@ -50,7 +50,14 @@ class InlineLoginHandlerImpl : public InlineLoginHandler, ...@@ -50,7 +50,14 @@ class InlineLoginHandlerImpl : public InlineLoginHandler,
private: private:
// InlineLoginHandler overrides: // InlineLoginHandler overrides:
void SetExtraInitParams(base::DictionaryValue& params) override; void SetExtraInitParams(base::DictionaryValue& params) override;
void CompleteLogin(const base::ListValue* args) override; void CompleteLogin(const std::string& email,
const std::string& password,
const std::string& gaia_id,
const std::string& auth_code,
bool skip_for_now,
bool trusted,
bool trusted_found,
bool choose_what_to_sync) override;
// This struct exists to pass paramters to the FinishCompleteLogin() method, // This struct exists to pass paramters to the FinishCompleteLogin() method,
// since the base::Bind() call does not support this many template args. // since the base::Bind() call does not support this many template args.
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/child_process_host.h" #include "content/public/common/child_process_host.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/api/activity_log/web_request_constants.h" #include "extensions/browser/api/activity_log/web_request_constants.h"
#include "extensions/browser/api/declarative/rules_registry_service.h" #include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/api/declarative_net_request/ruleset_manager.h" #include "extensions/browser/api/declarative_net_request/ruleset_manager.h"
...@@ -65,6 +66,7 @@ ...@@ -65,6 +66,7 @@
#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/guest_view/guest_view_events.h" #include "extensions/browser/guest_view/guest_view_events.h"
#include "extensions/browser/guest_view/web_view/web_view_constants.h" #include "extensions/browser/guest_view/web_view/web_view_constants.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/browser/info_map.h" #include "extensions/browser/info_map.h"
#include "extensions/browser/io_thread_extension_message_filter.h" #include "extensions/browser/io_thread_extension_message_filter.h"
#include "extensions/browser/runtime_data.h" #include "extensions/browser/runtime_data.h"
...@@ -75,6 +77,7 @@ ...@@ -75,6 +77,7 @@
#include "extensions/common/event_filtering_info.h" #include "extensions/common/event_filtering_info.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "extensions/common/features/feature.h" #include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/permissions/permissions_data.h" #include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/url_pattern.h" #include "extensions/common/url_pattern.h"
#include "extensions/strings/grit/extensions_strings.h" #include "extensions/strings/grit/extensions_strings.h"
...@@ -594,8 +597,31 @@ bool WebRequestAPI::MaybeProxyURLLoaderFactory( ...@@ -594,8 +597,31 @@ bool WebRequestAPI::MaybeProxyURLLoaderFactory(
bool is_navigation, bool is_navigation,
network::mojom::URLLoaderFactoryRequest* factory_request) { network::mojom::URLLoaderFactoryRequest* factory_request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!MayHaveProxies()) if (!MayHaveProxies()) {
return false; bool skip_proxy = true;
// There are a few internal WebUIs that use WebView tag that are whitelisted
// for webRequest.
if (frame) {
auto* web_contents = content::WebContents::FromRenderFrameHost(frame);
if (web_contents && WebViewGuest::IsGuest(web_contents)) {
auto* guest_web_contents =
WebViewGuest::GetTopLevelWebContents(web_contents);
auto& guest_url = guest_web_contents->GetURL();
if (guest_url.SchemeIs(content::kChromeUIScheme)) {
auto* feature = FeatureProvider::GetAPIFeature("webRequestInternal");
if (feature
->IsAvailableToContext(nullptr, Feature::WEBUI_CONTEXT,
guest_url)
.is_available()) {
skip_proxy = false;
}
}
}
}
if (skip_proxy)
return false;
}
auto proxied_request = std::move(*factory_request); auto proxied_request = std::move(*factory_request);
network::mojom::URLLoaderFactoryPtrInfo target_factory_info; network::mojom::URLLoaderFactoryPtrInfo target_factory_info;
......
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