1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/login/login_prompt.h" 6 7 #include "base/utf_string_conversions.h" 8 #include "chrome/browser/password_manager/password_manager.h" 9 #include "chrome/browser/tab_contents/tab_util.h" 10 #include "chrome/browser/ui/views/login_view.h" 11 #include "content/browser/browser_thread.h" 12 #include "content/browser/renderer_host/render_process_host.h" 13 #include "content/browser/renderer_host/render_view_host.h" 14 #include "content/browser/renderer_host/resource_dispatcher_host.h" 15 #include "content/browser/tab_contents/tab_contents.h" 16 #include "grit/generated_resources.h" 17 #include "net/url_request/url_request.h" 18 #include "ui/base/l10n/l10n_util.h" 19 #include "views/window/dialog_delegate.h" 20 21 using webkit_glue::PasswordForm; 22 23 // ---------------------------------------------------------------------------- 24 // LoginHandlerWin 25 26 // This class simply forwards the authentication from the LoginView (on 27 // the UI thread) to the net::URLRequest (on the I/O thread). 28 // This class uses ref counting to ensure that it lives until all InvokeLaters 29 // have been called. 30 class LoginHandlerWin : public LoginHandler, 31 public ConstrainedDialogDelegate { 32 public: 33 LoginHandlerWin(net::AuthChallengeInfo* auth_info, net::URLRequest* request) 34 : LoginHandler(auth_info, request) { 35 } 36 37 // LoginModelObserver implementation. 38 virtual void OnAutofillDataAvailable(const std::wstring& username, 39 const std::wstring& password) OVERRIDE { 40 // Nothing to do here since LoginView takes care of autofil for win. 41 } 42 43 // views::DialogDelegate methods: 44 virtual std::wstring GetDialogButtonLabel( 45 MessageBoxFlags::DialogButton button) const OVERRIDE { 46 if (button == MessageBoxFlags::DIALOGBUTTON_OK) 47 return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL); 48 return DialogDelegate::GetDialogButtonLabel(button); 49 } 50 51 virtual std::wstring GetWindowTitle() const OVERRIDE { 52 return l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_TITLE); 53 } 54 55 virtual void WindowClosing() OVERRIDE { 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 57 58 TabContents* tab = GetTabContentsForLogin(); 59 if (tab) 60 tab->render_view_host()->set_ignore_input_events(false); 61 62 // Reference is no longer valid. 63 SetDialog(NULL); 64 65 CancelAuth(); 66 } 67 68 virtual void DeleteDelegate() OVERRIDE { 69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 70 71 // The constrained window is going to delete itself; clear our pointer. 72 SetDialog(NULL); 73 SetModel(NULL); 74 75 ReleaseSoon(); 76 } 77 78 virtual bool Cancel() OVERRIDE { 79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 80 81 CancelAuth(); 82 return true; 83 } 84 85 virtual bool Accept() OVERRIDE { 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 87 88 SetAuth(login_view_->GetUsername(), login_view_->GetPassword()); 89 return true; 90 } 91 92 virtual views::View* GetInitiallyFocusedView() OVERRIDE { 93 return login_view_->GetInitiallyFocusedView(); 94 } 95 96 virtual views::View* GetContentsView() OVERRIDE { 97 return login_view_; 98 } 99 100 // LoginHandler: 101 102 virtual void BuildViewForPasswordManager( 103 PasswordManager* manager, 104 const string16& explanation) OVERRIDE { 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 106 107 // Create a new LoginView and set the model for it. The model 108 // (password manager) is owned by the view's parent TabContents, 109 // so natural destruction order means we don't have to worry about 110 // disassociating the model from the view, because the view will 111 // be deleted before the password manager. 112 login_view_ = new LoginView(UTF16ToWideHack(explanation), manager); 113 114 // Scary thread safety note: This can potentially be called *after* SetAuth 115 // or CancelAuth (say, if the request was cancelled before the UI thread got 116 // control). However, that's OK since any UI interaction in those functions 117 // will occur via an InvokeLater on the UI thread, which is guaranteed 118 // to happen after this is called (since this was InvokeLater'd first). 119 SetDialog(GetTabContentsForLogin()->CreateConstrainedDialog(this)); 120 NotifyAuthNeeded(); 121 } 122 123 private: 124 friend class base::RefCountedThreadSafe<LoginHandlerWin>; 125 friend class LoginPrompt; 126 127 ~LoginHandlerWin() {} 128 129 // The LoginView that contains the user's login information 130 LoginView* login_view_; 131 132 DISALLOW_COPY_AND_ASSIGN(LoginHandlerWin); 133 }; 134 135 // static 136 LoginHandler* LoginHandler::Create(net::AuthChallengeInfo* auth_info, 137 net::URLRequest* request) { 138 return new LoginHandlerWin(auth_info, request); 139 } 140