Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: chrome/browser/ui/login/login_prompt.cc

Issue 1395473003: Follow-up clean-up in LoginHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove accessors Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/login/login_prompt.h ('k') | chrome/browser/ui/views/login_prompt_views.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/login/login_prompt.h" 5 #include "chrome/browser/ui/login/login_prompt.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 using content::BrowserThread; 48 using content::BrowserThread;
49 using content::NavigationController; 49 using content::NavigationController;
50 using content::RenderViewHost; 50 using content::RenderViewHost;
51 using content::RenderViewHostDelegate; 51 using content::RenderViewHostDelegate;
52 using content::ResourceDispatcherHost; 52 using content::ResourceDispatcherHost;
53 using content::ResourceRequestInfo; 53 using content::ResourceRequestInfo;
54 using content::WebContents; 54 using content::WebContents;
55 55
56 class LoginHandlerImpl; 56 class LoginHandlerImpl;
57 57
58 namespace {
59
58 // Helper to remove the ref from an net::URLRequest to the LoginHandler. 60 // Helper to remove the ref from an net::URLRequest to the LoginHandler.
59 // Should only be called from the IO thread, since it accesses an 61 // Should only be called from the IO thread, since it accesses an
60 // net::URLRequest. 62 // net::URLRequest.
61 void ResetLoginHandlerForRequest(net::URLRequest* request) { 63 void ResetLoginHandlerForRequest(net::URLRequest* request) {
62 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request); 64 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request);
63 } 65 }
64 66
65 // Get the signon_realm under which this auth info should be stored. 67 // Helper to create a PasswordForm for PasswordManager to start looking for
66 // 68 // saved credentials.
67 // The format of the signon_realm for proxy auth is: 69 PasswordForm MakeInputForPasswordManager(const GURL& request_url,
68 // proxy-host/auth-realm 70 net::AuthChallengeInfo* auth_info) {
69 // The format of the signon_realm for server auth is: 71 PasswordForm dialog_form;
70 // url-scheme://url-host[:url-port]/auth-realm 72 if (base::LowerCaseEqualsASCII(auth_info->scheme, "basic")) {
71 // 73 dialog_form.scheme = PasswordForm::SCHEME_BASIC;
72 // Be careful when changing this function, since you could make existing 74 } else if (base::LowerCaseEqualsASCII(auth_info->scheme, "digest")) {
73 // saved logins un-retrievable. 75 dialog_form.scheme = PasswordForm::SCHEME_DIGEST;
74 std::string GetSignonRealm(const GURL& url,
75 const net::AuthChallengeInfo& auth_info) {
76 std::string signon_realm;
77 if (auth_info.is_proxy) {
78 signon_realm = auth_info.challenger.ToString();
79 signon_realm.append("/");
80 } else { 76 } else {
81 // Take scheme, host, and port from the url. 77 dialog_form.scheme = PasswordForm::SCHEME_OTHER;
82 signon_realm = url.GetOrigin().spec();
83 // This ends with a "/".
84 } 78 }
85 signon_realm.append(auth_info.realm); 79 std::string host_and_port(auth_info->challenger.ToString());
86 return signon_realm; 80 if (auth_info->is_proxy) {
81 std::string origin = host_and_port;
82 // We don't expect this to already start with http:// or https://.
83 DCHECK(origin.find("http://") != 0 && origin.find("https://") != 0);
84 origin = std::string("http://") + origin;
85 dialog_form.origin = GURL(origin);
86 } else if (!auth_info->challenger.Equals(
87 net::HostPortPair::FromURL(request_url))) {
88 dialog_form.origin = GURL();
89 NOTREACHED(); // crbug.com/32718
90 } else {
91 dialog_form.origin = GURL(request_url.scheme() + "://" + host_and_port);
92 }
93 dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info);
94 return dialog_form;
87 } 95 }
88 96
97 void ShowLoginPrompt(const GURL& request_url,
98 net::AuthChallengeInfo* auth_info,
99 LoginHandler* handler) {
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101 WebContents* parent_contents = handler->GetWebContentsForLogin();
102 if (!parent_contents)
103 return;
104 prerender::PrerenderContents* prerender_contents =
105 prerender::PrerenderContents::FromWebContents(parent_contents);
106 if (prerender_contents) {
107 prerender_contents->Destroy(prerender::FINAL_STATUS_AUTH_NEEDED);
108 return;
109 }
110
111 // The realm is controlled by the remote server, so there is no reason
112 // to believe it is of a reasonable length.
113 base::string16 elided_realm;
114 gfx::ElideString(base::UTF8ToUTF16(auth_info->realm), 120, &elided_realm);
115
116 std::string languages;
117 content::WebContents* web_contents = handler->GetWebContentsForLogin();
118 if (web_contents) {
119 Profile* profile =
120 Profile::FromBrowserContext(web_contents->GetBrowserContext());
121 if (profile)
122 languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
123 }
124
125 base::string16 authority =
126 url_formatter::FormatUrlForSecurityDisplay(request_url, languages);
127 base::string16 explanation =
128 elided_realm.empty()
129 ? l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION_NO_REALM,
130 authority)
131 : l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION, authority,
132 elided_realm);
133
134 password_manager::PasswordManager* password_manager =
135 handler->GetPasswordManagerForLogin();
136
137 if (!password_manager) {
138 #if defined(ENABLE_EXTENSIONS)
139 // A WebContents in a <webview> (a GuestView type) does not have a password
140 // manager, but still needs to be able to show login prompts.
141 if (guest_view::GuestViewBase::FromWebContents(parent_contents)) {
142 handler->BuildViewWithoutPasswordManager(explanation);
143 return;
144 }
145 #endif
146 handler->CancelAuth();
147 return;
148 }
149
150 if (password_manager && password_manager->client()->IsLoggingActive()) {
151 password_manager::BrowserSavePasswordProgressLogger logger(
152 password_manager->client());
153 logger.LogMessage(
154 autofill::SavePasswordProgressLogger::STRING_SHOW_LOGIN_PROMPT_METHOD);
155 }
156
157 PasswordForm observed_form(
158 MakeInputForPasswordManager(request_url, auth_info));
159 handler->BuildViewWithPasswordManager(explanation, password_manager,
160 observed_form);
161 }
162
163 } // namespace
164
89 // ---------------------------------------------------------------------------- 165 // ----------------------------------------------------------------------------
90 // LoginHandler 166 // LoginHandler
91 167
92 LoginHandler::LoginModelData::LoginModelData( 168 LoginHandler::LoginModelData::LoginModelData(
93 password_manager::LoginModel* login_model, 169 password_manager::LoginModel* login_model,
94 const autofill::PasswordForm& observed_form) 170 const autofill::PasswordForm& observed_form)
95 : model(login_model), form(observed_form) { 171 : model(login_model), form(observed_form) {
96 DCHECK(model); 172 DCHECK(model);
97 } 173 }
98 174
99 LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, 175 LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info,
100 net::URLRequest* request) 176 net::URLRequest* request)
101 : handled_auth_(false), 177 : handled_auth_(false),
102 auth_info_(auth_info), 178 auth_info_(auth_info),
103 request_(request), 179 request_(request),
104 http_network_session_( 180 http_network_session_(
105 request_->context()->http_transaction_factory()->GetSession()), 181 request_->context()->http_transaction_factory()->GetSession()),
106 password_manager_(NULL), 182 password_manager_(NULL),
107 login_model_(NULL) { 183 login_model_(NULL) {
108 // This constructor is called on the I/O thread, so we cannot load the nib 184 // This constructor is called on the I/O thread, so we cannot load the nib
109 // here. BuildView() will be invoked on the UI thread later, so wait with 185 // here. BuildViewImpl() will be invoked on the UI thread later, so wait with
110 // loading the nib until then. 186 // loading the nib until then.
111 DCHECK(request_) << "LoginHandler constructed with NULL request"; 187 DCHECK(request_) << "LoginHandler constructed with NULL request";
112 DCHECK(auth_info_.get()) << "LoginHandler constructed with NULL auth info"; 188 DCHECK(auth_info_.get()) << "LoginHandler constructed with NULL auth info";
113 189
114 AddRef(); // matched by LoginHandler::ReleaseSoon(). 190 AddRef(); // matched by LoginHandler::ReleaseSoon().
115 191
116 BrowserThread::PostTask( 192 BrowserThread::PostTask(
117 BrowserThread::UI, FROM_HERE, 193 BrowserThread::UI, FROM_HERE,
118 base::Bind(&LoginHandler::AddObservers, this)); 194 base::Bind(&LoginHandler::AddObservers, this));
119 195
120 if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame( 196 if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame(
121 &render_process_host_id_, &render_frame_id_)) { 197 &render_process_host_id_, &render_frame_id_)) {
122 NOTREACHED(); 198 NOTREACHED();
123 } 199 }
124 } 200 }
125 201
126 void LoginHandler::OnRequestCancelled() { 202 void LoginHandler::OnRequestCancelled() {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) <<
128 "Why is OnRequestCancelled called from the UI thread?"; 204 "Why is OnRequestCancelled called from the UI thread?";
129 205
130 // Reference is no longer valid. 206 // Reference is no longer valid.
131 request_ = NULL; 207 request_ = NULL;
132 208
133 // Give up on auth if the request was cancelled. 209 // Give up on auth if the request was cancelled.
134 CancelAuth(); 210 CancelAuth();
135 } 211 }
136 212
137 void LoginHandler::SetPasswordForm(const autofill::PasswordForm& form) { 213 void LoginHandler::BuildViewWithPasswordManager(
138 password_form_ = form; 214 const base::string16& explanation,
215 password_manager::PasswordManager* password_manager,
216 const autofill::PasswordForm& observed_form) {
217 password_manager_ = password_manager;
218 password_form_ = observed_form;
219 LoginHandler::LoginModelData model_data(password_manager, observed_form);
220 BuildViewImpl(explanation, &model_data);
139 } 221 }
140 222
141 void LoginHandler::SetPasswordManager( 223 void LoginHandler::BuildViewWithoutPasswordManager(
142 password_manager::PasswordManager* password_manager) { 224 const base::string16& explanation) {
143 password_manager_ = password_manager; 225 BuildViewImpl(explanation, nullptr);
144 } 226 }
145 227
146 WebContents* LoginHandler::GetWebContentsForLogin() const { 228 WebContents* LoginHandler::GetWebContentsForLogin() const {
147 DCHECK_CURRENTLY_ON(BrowserThread::UI); 229 DCHECK_CURRENTLY_ON(BrowserThread::UI);
148 230
149 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( 231 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
150 render_process_host_id_, render_frame_id_); 232 render_process_host_id_, render_frame_id_);
151 return WebContents::FromRenderFrameHost(rfh); 233 return WebContents::FromRenderFrameHost(rfh);
152 } 234 }
153 235
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 base::AutoLock lock(handled_auth_lock_); 357 base::AutoLock lock(handled_auth_lock_);
276 bool was_handled = handled_auth_; 358 bool was_handled = handled_auth_;
277 return was_handled; 359 return was_handled;
278 } 360 }
279 361
280 LoginHandler::~LoginHandler() { 362 LoginHandler::~LoginHandler() {
281 ResetModel(); 363 ResetModel();
282 } 364 }
283 365
284 void LoginHandler::SetModel(LoginModelData model_data) { 366 void LoginHandler::SetModel(LoginModelData model_data) {
285 if (login_model_) 367 ResetModel();
286 login_model_->RemoveObserver(this);
287 login_model_ = model_data.model; 368 login_model_ = model_data.model;
288 login_model_->AddObserverAndDeliverCredentials(this, model_data.form); 369 login_model_->AddObserverAndDeliverCredentials(this, model_data.form);
289 } 370 }
290 371
291 void LoginHandler::ResetModel() { 372 void LoginHandler::ResetModel() {
292 if (login_model_) 373 if (login_model_)
293 login_model_->RemoveObserver(this); 374 login_model_->RemoveObserver(this);
294 login_model_ = nullptr; 375 login_model_ = nullptr;
295 } 376 }
296 377
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 if (!requesting_contents) 512 if (!requesting_contents)
432 return; 513 return;
433 // If a (blank) login interstitial was displayed, proceed so that the 514 // If a (blank) login interstitial was displayed, proceed so that the
434 // navigation is committed. 515 // navigation is committed.
435 content::InterstitialPage* interstitial_page = 516 content::InterstitialPage* interstitial_page =
436 requesting_contents->GetInterstitialPage(); 517 requesting_contents->GetInterstitialPage();
437 if (interstitial_page) 518 if (interstitial_page)
438 interstitial_page->Proceed(); 519 interstitial_page->Proceed();
439 } 520 }
440 521
441 // Helper to create a PasswordForm for PasswordManager to start looking for
442 // saved credentials.
443 PasswordForm MakeInputForPasswordManager(const GURL& request_url,
444 net::AuthChallengeInfo* auth_info,
445 LoginHandler* handler) {
446 PasswordForm dialog_form;
447 if (base::LowerCaseEqualsASCII(auth_info->scheme, "basic")) {
448 dialog_form.scheme = PasswordForm::SCHEME_BASIC;
449 } else if (base::LowerCaseEqualsASCII(auth_info->scheme, "digest")) {
450 dialog_form.scheme = PasswordForm::SCHEME_DIGEST;
451 } else {
452 dialog_form.scheme = PasswordForm::SCHEME_OTHER;
453 }
454 std::string host_and_port(auth_info->challenger.ToString());
455 if (auth_info->is_proxy) {
456 std::string origin = host_and_port;
457 // We don't expect this to already start with http:// or https://.
458 DCHECK(origin.find("http://") != 0 && origin.find("https://") != 0);
459 origin = std::string("http://") + origin;
460 dialog_form.origin = GURL(origin);
461 } else if (!auth_info->challenger.Equals(
462 net::HostPortPair::FromURL(request_url))) {
463 dialog_form.origin = GURL();
464 NOTREACHED(); // crbug.com/32718
465 } else {
466 dialog_form.origin = GURL(request_url.scheme() + "://" + host_and_port);
467 }
468 dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info);
469 // Set the password form for the handler (by copy).
470 handler->SetPasswordForm(dialog_form);
471 return dialog_form;
472 }
473
474 void ShowLoginPrompt(const GURL& request_url,
475 net::AuthChallengeInfo* auth_info,
476 LoginHandler* handler) {
477 DCHECK_CURRENTLY_ON(BrowserThread::UI);
478 WebContents* parent_contents = handler->GetWebContentsForLogin();
479 if (!parent_contents)
480 return;
481 prerender::PrerenderContents* prerender_contents =
482 prerender::PrerenderContents::FromWebContents(parent_contents);
483 if (prerender_contents) {
484 prerender_contents->Destroy(prerender::FINAL_STATUS_AUTH_NEEDED);
485 return;
486 }
487
488 // The realm is controlled by the remote server, so there is no reason
489 // to believe it is of a reasonable length.
490 base::string16 elided_realm;
491 gfx::ElideString(base::UTF8ToUTF16(auth_info->realm), 120, &elided_realm);
492
493 std::string languages;
494 content::WebContents* web_contents = handler->GetWebContentsForLogin();
495 if (web_contents) {
496 Profile* profile =
497 Profile::FromBrowserContext(web_contents->GetBrowserContext());
498 if (profile)
499 languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
500 }
501
502 base::string16 authority =
503 url_formatter::FormatUrlForSecurityDisplay(request_url, languages);
504 base::string16 explanation =
505 elided_realm.empty()
506 ? l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION_NO_REALM,
507 authority)
508 : l10n_util::GetStringFUTF16(IDS_LOGIN_DIALOG_DESCRIPTION, authority,
509 elided_realm);
510
511 password_manager::PasswordManager* password_manager =
512 handler->GetPasswordManagerForLogin();
513
514 if (!password_manager) {
515 #if defined(ENABLE_EXTENSIONS)
516 // A WebContents in a <webview> (a GuestView type) does not have a password
517 // manager, but still needs to be able to show login prompts.
518 if (guest_view::GuestViewBase::FromWebContents(parent_contents)) {
519 handler->BuildView(explanation, nullptr);
520 return;
521 }
522 #endif
523 handler->CancelAuth();
524 return;
525 }
526
527 if (password_manager && password_manager->client()->IsLoggingActive()) {
528 password_manager::BrowserSavePasswordProgressLogger logger(
529 password_manager->client());
530 logger.LogMessage(
531 autofill::SavePasswordProgressLogger::STRING_SHOW_LOGIN_PROMPT_METHOD);
532 }
533
534 handler->SetPasswordManager(password_manager);
535
536 PasswordForm observed_form(
537 MakeInputForPasswordManager(request_url, auth_info, handler));
538 LoginHandler::LoginModelData model_data(password_manager, observed_form);
539 handler->BuildView(explanation, &model_data);
540 }
541
542 // This callback is run on the UI thread and creates a constrained window with 522 // This callback is run on the UI thread and creates a constrained window with
543 // a LoginView to prompt the user. If the prompt is triggered because of 523 // a LoginView to prompt the user. If the prompt is triggered because of
544 // a cross origin navigation in the main frame, a blank interstitial is first 524 // a cross origin navigation in the main frame, a blank interstitial is first
545 // created which in turn creates the LoginView. Otherwise, a LoginView is 525 // created which in turn creates the LoginView. Otherwise, a LoginView is
546 // directly in this callback. In both cases, the response will be sent to 526 // directly in this callback. In both cases, the response will be sent to
547 // LoginHandler, which then routes it to the net::URLRequest on the I/O thread. 527 // LoginHandler, which then routes it to the net::URLRequest on the I/O thread.
548 void LoginDialogCallback(const GURL& request_url, 528 void LoginDialogCallback(const GURL& request_url,
549 net::AuthChallengeInfo* auth_info, 529 net::AuthChallengeInfo* auth_info,
550 LoginHandler* handler, 530 LoginHandler* handler,
551 bool is_main_frame) { 531 bool is_main_frame) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 net::URLRequest* request) { 583 net::URLRequest* request) {
604 bool is_main_frame = (request->load_flags() & net::LOAD_MAIN_FRAME) != 0; 584 bool is_main_frame = (request->load_flags() & net::LOAD_MAIN_FRAME) != 0;
605 LoginHandler* handler = LoginHandler::Create(auth_info, request); 585 LoginHandler* handler = LoginHandler::Create(auth_info, request);
606 BrowserThread::PostTask( 586 BrowserThread::PostTask(
607 BrowserThread::UI, FROM_HERE, 587 BrowserThread::UI, FROM_HERE,
608 base::Bind(&LoginDialogCallback, request->url(), 588 base::Bind(&LoginDialogCallback, request->url(),
609 make_scoped_refptr(auth_info), make_scoped_refptr(handler), 589 make_scoped_refptr(auth_info), make_scoped_refptr(handler),
610 is_main_frame)); 590 is_main_frame));
611 return handler; 591 return handler;
612 } 592 }
593
594 // Get the signon_realm under which this auth info should be stored.
595 //
596 // The format of the signon_realm for proxy auth is:
597 // proxy-host/auth-realm
598 // The format of the signon_realm for server auth is:
599 // url-scheme://url-host[:url-port]/auth-realm
600 //
601 // Be careful when changing this function, since you could make existing
602 // saved logins un-retrievable.
603 std::string GetSignonRealm(const GURL& url,
604 const net::AuthChallengeInfo& auth_info) {
605 std::string signon_realm;
606 if (auth_info.is_proxy) {
607 signon_realm = auth_info.challenger.ToString();
608 signon_realm.append("/");
609 } else {
610 // Take scheme, host, and port from the url.
611 signon_realm = url.GetOrigin().spec();
612 // This ends with a "/".
613 }
614 signon_realm.append(auth_info.realm);
615 return signon_realm;
616 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/login/login_prompt.h ('k') | chrome/browser/ui/views/login_prompt_views.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698