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
21using 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.
30class 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
136LoginHandler* LoginHandler::Create(net::AuthChallengeInfo* auth_info,
137                                   net::URLRequest* request) {
138  return new LoginHandlerWin(auth_info, request);
139}
140