Index: chrome/browser/ui/login/login_prompt.cc |
diff --git a/chrome/browser/ui/login/login_prompt.cc b/chrome/browser/ui/login/login_prompt.cc |
index 6ee6149a5426eee6081416010753ca53800e7154..5f8c298c9562d8a7b9ea433a2480b7ea9475138f 100644 |
--- a/chrome/browser/ui/login/login_prompt.cc |
+++ b/chrome/browser/ui/login/login_prompt.cc |
@@ -55,6 +55,8 @@ using content::WebContents; |
class LoginHandlerImpl; |
+namespace { |
+ |
// Helper to remove the ref from an net::URLRequest to the LoginHandler. |
// Should only be called from the IO thread, since it accesses an |
// net::URLRequest. |
@@ -62,30 +64,104 @@ void ResetLoginHandlerForRequest(net::URLRequest* request) { |
ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request); |
} |
-// Get the signon_realm under which this auth info should be stored. |
-// |
-// The format of the signon_realm for proxy auth is: |
-// proxy-host/auth-realm |
-// The format of the signon_realm for server auth is: |
-// url-scheme://url-host[:url-port]/auth-realm |
-// |
-// Be careful when changing this function, since you could make existing |
-// saved logins un-retrievable. |
-std::string GetSignonRealm(const GURL& url, |
- const net::AuthChallengeInfo& auth_info) { |
- std::string signon_realm; |
- if (auth_info.is_proxy) { |
- signon_realm = auth_info.challenger.ToString(); |
- signon_realm.append("/"); |
+// Helper to create a PasswordForm for PasswordManager to start looking for |
+// saved credentials. |
+PasswordForm MakeInputForPasswordManager(const GURL& request_url, |
+ net::AuthChallengeInfo* auth_info) { |
+ PasswordForm dialog_form; |
+ if (base::LowerCaseEqualsASCII(auth_info->scheme, "basic")) { |
+ dialog_form.scheme = PasswordForm::SCHEME_BASIC; |
+ } else if (base::LowerCaseEqualsASCII(auth_info->scheme, "digest")) { |
+ dialog_form.scheme = PasswordForm::SCHEME_DIGEST; |
} else { |
- // Take scheme, host, and port from the url. |
- signon_realm = url.GetOrigin().spec(); |
- // This ends with a "/". |
+ dialog_form.scheme = PasswordForm::SCHEME_OTHER; |
} |
- signon_realm.append(auth_info.realm); |
- return signon_realm; |
+ std::string host_and_port(auth_info->challenger.ToString()); |
+ if (auth_info->is_proxy) { |
+ std::string origin = host_and_port; |
+ // We don't expect this to already start with http:// or https://. |
+ DCHECK(origin.find("http://") != 0 && origin.find("https://") != 0); |
+ origin = std::string("http://") + origin; |
+ dialog_form.origin = GURL(origin); |
+ } else if (!auth_info->challenger.Equals( |
+ net::HostPortPair::FromURL(request_url))) { |
+ dialog_form.origin = GURL(); |
+ NOTREACHED(); // crbug.com/32718 |
+ } else { |
+ dialog_form.origin = GURL(request_url.scheme() + "://" + host_and_port); |
+ } |
+ dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info); |
+ return dialog_form; |
} |
+void ShowLoginPrompt(const GURL& request_url, |
+ net::AuthChallengeInfo* auth_info, |
+ LoginHandler* handler) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ WebContents* parent_contents = handler->GetWebContentsForLogin(); |
+ if (!parent_contents) |
+ return; |
+ prerender::PrerenderContents* prerender_contents = |
+ prerender::PrerenderContents::FromWebContents(parent_contents); |
+ if (prerender_contents) { |
+ prerender_contents->Destroy(prerender::FINAL_STATUS_AUTH_NEEDED); |
+ return; |
+ } |
+ |
+ // The realm is controlled by the remote server, so there is no reason |
+ // to believe it is of a reasonable length. |
+ base::string16 elided_realm; |
+ gfx::ElideString(base::UTF8ToUTF16(auth_info->realm), 120, &elided_realm); |
+ |
+ std::string languages; |
+ content::WebContents* web_contents = handler->GetWebContentsForLogin(); |
+ if (web_contents) { |
+ Profile* profile = |
+ Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
+ if (profile) |
+ languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); |
+ } |
+ |
+ base::string16 authority = |
+ url_formatter::FormatUrlForSecurityDisplay(request_url, languages); |
+ base::string16 explanation = |
+ elided_realm.empty() |
+ ? l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION_NO_REALM, |
+ authority) |
+ : l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION, authority, |
+ elided_realm); |
+ |
+ password_manager::PasswordManager* password_manager = |
+ handler->GetPasswordManagerForLogin(); |
+ |
+ if (!password_manager) { |
+#if defined(ENABLE_EXTENSIONS) |
+ // A WebContents in a <webview> (a GuestView type) does not have a password |
+ // manager, but still needs to be able to show login prompts. |
+ if (guest_view::GuestViewBase::FromWebContents(parent_contents)) { |
+ handler->BuildViewWithoutPasswordManager(explanation); |
+ return; |
+ } |
+#endif |
+ handler->CancelAuth(); |
+ return; |
+ } |
+ |
+ if (password_manager && password_manager->client()->IsLoggingActive()) { |
+ password_manager::BrowserSavePasswordProgressLogger logger( |
+ password_manager->client()); |
+ logger.LogMessage( |
+ autofill::SavePasswordProgressLogger::STRING_SHOW_LOGIN_PROMPT_METHOD); |
+ } |
+ |
+ PasswordForm observed_form( |
+ MakeInputForPasswordManager(request_url, auth_info)); |
+ handler->BuildViewWithPasswordManager(explanation, password_manager, |
+ observed_form); |
+} |
+ |
+} // namespace |
+ |
// ---------------------------------------------------------------------------- |
// LoginHandler |
@@ -106,7 +182,7 @@ LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, |
password_manager_(NULL), |
login_model_(NULL) { |
// This constructor is called on the I/O thread, so we cannot load the nib |
- // here. BuildView() will be invoked on the UI thread later, so wait with |
+ // here. BuildViewImpl() will be invoked on the UI thread later, so wait with |
// loading the nib until then. |
DCHECK(request_) << "LoginHandler constructed with NULL request"; |
DCHECK(auth_info_.get()) << "LoginHandler constructed with NULL auth info"; |
@@ -134,13 +210,19 @@ void LoginHandler::OnRequestCancelled() { |
CancelAuth(); |
} |
-void LoginHandler::SetPasswordForm(const autofill::PasswordForm& form) { |
- password_form_ = form; |
+void LoginHandler::BuildViewWithPasswordManager( |
+ const base::string16& explanation, |
+ password_manager::PasswordManager* password_manager, |
+ const autofill::PasswordForm& observed_form) { |
+ password_manager_ = password_manager; |
+ password_form_ = observed_form; |
+ LoginHandler::LoginModelData model_data(password_manager, observed_form); |
+ BuildViewImpl(explanation, &model_data); |
} |
-void LoginHandler::SetPasswordManager( |
- password_manager::PasswordManager* password_manager) { |
- password_manager_ = password_manager; |
+void LoginHandler::BuildViewWithoutPasswordManager( |
+ const base::string16& explanation) { |
+ BuildViewImpl(explanation, nullptr); |
} |
WebContents* LoginHandler::GetWebContentsForLogin() const { |
@@ -282,8 +364,7 @@ LoginHandler::~LoginHandler() { |
} |
void LoginHandler::SetModel(LoginModelData model_data) { |
- if (login_model_) |
- login_model_->RemoveObserver(this); |
+ ResetModel(); |
login_model_ = model_data.model; |
login_model_->AddObserverAndDeliverCredentials(this, model_data.form); |
} |
@@ -438,107 +519,6 @@ void LoginHandler::CloseContentsDeferred() { |
interstitial_page->Proceed(); |
} |
-// Helper to create a PasswordForm for PasswordManager to start looking for |
-// saved credentials. |
-PasswordForm MakeInputForPasswordManager(const GURL& request_url, |
- net::AuthChallengeInfo* auth_info, |
- LoginHandler* handler) { |
- PasswordForm dialog_form; |
- if (base::LowerCaseEqualsASCII(auth_info->scheme, "basic")) { |
- dialog_form.scheme = PasswordForm::SCHEME_BASIC; |
- } else if (base::LowerCaseEqualsASCII(auth_info->scheme, "digest")) { |
- dialog_form.scheme = PasswordForm::SCHEME_DIGEST; |
- } else { |
- dialog_form.scheme = PasswordForm::SCHEME_OTHER; |
- } |
- std::string host_and_port(auth_info->challenger.ToString()); |
- if (auth_info->is_proxy) { |
- std::string origin = host_and_port; |
- // We don't expect this to already start with http:// or https://. |
- DCHECK(origin.find("http://") != 0 && origin.find("https://") != 0); |
- origin = std::string("http://") + origin; |
- dialog_form.origin = GURL(origin); |
- } else if (!auth_info->challenger.Equals( |
- net::HostPortPair::FromURL(request_url))) { |
- dialog_form.origin = GURL(); |
- NOTREACHED(); // crbug.com/32718 |
- } else { |
- dialog_form.origin = GURL(request_url.scheme() + "://" + host_and_port); |
- } |
- dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info); |
- // Set the password form for the handler (by copy). |
- handler->SetPasswordForm(dialog_form); |
- return dialog_form; |
-} |
- |
-void ShowLoginPrompt(const GURL& request_url, |
- net::AuthChallengeInfo* auth_info, |
- LoginHandler* handler) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- WebContents* parent_contents = handler->GetWebContentsForLogin(); |
- if (!parent_contents) |
- return; |
- prerender::PrerenderContents* prerender_contents = |
- prerender::PrerenderContents::FromWebContents(parent_contents); |
- if (prerender_contents) { |
- prerender_contents->Destroy(prerender::FINAL_STATUS_AUTH_NEEDED); |
- return; |
- } |
- |
- // The realm is controlled by the remote server, so there is no reason |
- // to believe it is of a reasonable length. |
- base::string16 elided_realm; |
- gfx::ElideString(base::UTF8ToUTF16(auth_info->realm), 120, &elided_realm); |
- |
- std::string languages; |
- content::WebContents* web_contents = handler->GetWebContentsForLogin(); |
- if (web_contents) { |
- Profile* profile = |
- Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
- if (profile) |
- languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); |
- } |
- |
- base::string16 authority = |
- url_formatter::FormatUrlForSecurityDisplay(request_url, languages); |
- base::string16 explanation = |
- elided_realm.empty() |
- ? l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION_NO_REALM, |
- authority) |
- : l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION, authority, |
- elided_realm); |
- |
- password_manager::PasswordManager* password_manager = |
- handler->GetPasswordManagerForLogin(); |
- |
- if (!password_manager) { |
-#if defined(ENABLE_EXTENSIONS) |
- // A WebContents in a <webview> (a GuestView type) does not have a password |
- // manager, but still needs to be able to show login prompts. |
- if (guest_view::GuestViewBase::FromWebContents(parent_contents)) { |
- handler->BuildView(explanation, nullptr); |
- return; |
- } |
-#endif |
- handler->CancelAuth(); |
- return; |
- } |
- |
- if (password_manager && password_manager->client()->IsLoggingActive()) { |
- password_manager::BrowserSavePasswordProgressLogger logger( |
- password_manager->client()); |
- logger.LogMessage( |
- autofill::SavePasswordProgressLogger::STRING_SHOW_LOGIN_PROMPT_METHOD); |
- } |
- |
- handler->SetPasswordManager(password_manager); |
- |
- PasswordForm observed_form( |
- MakeInputForPasswordManager(request_url, auth_info, handler)); |
- LoginHandler::LoginModelData model_data(password_manager, observed_form); |
- handler->BuildView(explanation, &model_data); |
-} |
- |
// This callback is run on the UI thread and creates a constrained window with |
// a LoginView to prompt the user. If the prompt is triggered because of |
// a cross origin navigation in the main frame, a blank interstitial is first |
@@ -610,3 +590,27 @@ LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info, |
is_main_frame)); |
return handler; |
} |
+ |
+// Get the signon_realm under which this auth info should be stored. |
+// |
+// The format of the signon_realm for proxy auth is: |
+// proxy-host/auth-realm |
+// The format of the signon_realm for server auth is: |
+// url-scheme://url-host[:url-port]/auth-realm |
+// |
+// Be careful when changing this function, since you could make existing |
+// saved logins un-retrievable. |
+std::string GetSignonRealm(const GURL& url, |
+ const net::AuthChallengeInfo& auth_info) { |
+ std::string signon_realm; |
+ if (auth_info.is_proxy) { |
+ signon_realm = auth_info.challenger.ToString(); |
+ signon_realm.append("/"); |
+ } else { |
+ // Take scheme, host, and port from the url. |
+ signon_realm = url.GetOrigin().spec(); |
+ // This ends with a "/". |
+ } |
+ signon_realm.append(auth_info.realm); |
+ return signon_realm; |
+} |