• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/webui/options/password_manager_handler.h"
6 
7 #include "base/callback.h"
8 #include "base/string_number_conversions.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/browser/google/google_util.h"
12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/common/url_constants.h"
16 #include "content/common/notification_details.h"
17 #include "content/common/notification_source.h"
18 #include "grit/chromium_strings.h"
19 #include "grit/generated_resources.h"
20 #include "net/base/net_util.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "webkit/glue/password_form.h"
23 
PasswordManagerHandler()24 PasswordManagerHandler::PasswordManagerHandler()
25     : ALLOW_THIS_IN_INITIALIZER_LIST(populater_(this)),
26       ALLOW_THIS_IN_INITIALIZER_LIST(exception_populater_(this)) {
27 }
28 
~PasswordManagerHandler()29 PasswordManagerHandler::~PasswordManagerHandler() {
30   GetPasswordStore()->RemoveObserver(this);
31 }
32 
GetLocalizedValues(DictionaryValue * localized_strings)33 void PasswordManagerHandler::GetLocalizedValues(
34     DictionaryValue* localized_strings) {
35   DCHECK(localized_strings);
36 
37   static const OptionsStringResource resources[] = {
38     { "savedPasswordsTitle",
39       IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE },
40     { "passwordExceptionsTitle",
41       IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE },
42     { "passwordShowButton",
43       IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON },
44     { "passwordHideButton",
45       IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON },
46     { "passwordsSiteColumn",
47       IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN },
48     { "passwordsUsernameColumn",
49       IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN },
50     { "passwordsRemoveButton",
51       IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON },
52     { "passwordsNoPasswordsDescription",
53      IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION },
54     { "passwordsNoExceptionsDescription",
55      IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION },
56     { "passwordsRemoveAllButton",
57       IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON },
58     { "passwordsRemoveAllTitle",
59       IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS },
60     { "passwordsRemoveAllWarning",
61       IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS },
62   };
63 
64   RegisterStrings(localized_strings, resources, arraysize(resources));
65   RegisterTitle(localized_strings, "passwordsPage",
66                 IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE);
67 
68   localized_strings->SetString("passwordManagerLearnMoreURL",
69       google_util::AppendGoogleLocaleParam(
70           GURL(chrome::kPasswordManagerLearnMoreURL)).spec());
71 }
72 
Initialize()73 void PasswordManagerHandler::Initialize() {
74   show_passwords_.Init(prefs::kPasswordManagerAllowShowPasswords,
75                        web_ui_->GetProfile()->GetPrefs(), this);
76   // We should not cache web_ui_->GetProfile(). See crosbug.com/6304.
77   GetPasswordStore()->AddObserver(this);
78 }
79 
RegisterMessages()80 void PasswordManagerHandler::RegisterMessages() {
81   DCHECK(web_ui_);
82 
83   web_ui_->RegisterMessageCallback("updatePasswordLists",
84       NewCallback(this, &PasswordManagerHandler::UpdatePasswordLists));
85   web_ui_->RegisterMessageCallback("removeSavedPassword",
86       NewCallback(this, &PasswordManagerHandler::RemoveSavedPassword));
87   web_ui_->RegisterMessageCallback("removePasswordException",
88       NewCallback(this, &PasswordManagerHandler::RemovePasswordException));
89   web_ui_->RegisterMessageCallback("removeAllSavedPasswords",
90       NewCallback(this, &PasswordManagerHandler::RemoveAllSavedPasswords));
91   web_ui_->RegisterMessageCallback("removeAllPasswordExceptions", NewCallback(
92       this, &PasswordManagerHandler::RemoveAllPasswordExceptions));
93 }
94 
OnLoginsChanged()95 void PasswordManagerHandler::OnLoginsChanged() {
96   UpdatePasswordLists(NULL);
97 }
98 
GetPasswordStore()99 PasswordStore* PasswordManagerHandler::GetPasswordStore() {
100   return web_ui_->GetProfile()->GetPasswordStore(Profile::EXPLICIT_ACCESS);
101 }
102 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)103 void PasswordManagerHandler::Observe(NotificationType type,
104                                      const NotificationSource& source,
105                                      const NotificationDetails& details) {
106   if (type.value == NotificationType::PREF_CHANGED) {
107     std::string* pref_name = Details<std::string>(details).ptr();
108     if (*pref_name == prefs::kPasswordManagerAllowShowPasswords) {
109       UpdatePasswordLists(NULL);
110     }
111   }
112 
113   OptionsPageUIHandler::Observe(type, source, details);
114 }
115 
UpdatePasswordLists(const ListValue * args)116 void PasswordManagerHandler::UpdatePasswordLists(const ListValue* args) {
117   // Reset the current lists.
118   password_list_.reset();
119   password_exception_list_.reset();
120 
121   languages_ =
122       web_ui_->GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
123   populater_.Populate();
124   exception_populater_.Populate();
125 }
126 
RemoveSavedPassword(const ListValue * args)127 void PasswordManagerHandler::RemoveSavedPassword(const ListValue* args) {
128   std::string string_value = UTF16ToUTF8(ExtractStringValue(args));
129   int index;
130   base::StringToInt(string_value, &index);
131   GetPasswordStore()->RemoveLogin(*password_list_[index]);
132 }
133 
RemovePasswordException(const ListValue * args)134 void PasswordManagerHandler::RemovePasswordException(
135     const ListValue* args) {
136   std::string string_value = UTF16ToUTF8(ExtractStringValue(args));
137   int index;
138   base::StringToInt(string_value, &index);
139 
140   GetPasswordStore()->RemoveLogin(*password_exception_list_[index]);
141 }
142 
RemoveAllSavedPasswords(const ListValue * args)143 void PasswordManagerHandler::RemoveAllSavedPasswords(
144     const ListValue* args) {
145   // TODO(jhawkins): This will cause a list refresh for every password in the
146   // list. Add PasswordStore::RemoveAllLogins().
147   PasswordStore* store = GetPasswordStore();
148   for (size_t i = 0; i < password_list_.size(); ++i)
149     store->RemoveLogin(*password_list_[i]);
150 }
151 
RemoveAllPasswordExceptions(const ListValue * args)152 void PasswordManagerHandler::RemoveAllPasswordExceptions(
153     const ListValue* args) {
154   PasswordStore* store = GetPasswordStore();
155   for (size_t i = 0; i < password_exception_list_.size(); ++i)
156     store->RemoveLogin(*password_exception_list_[i]);
157 }
158 
SetPasswordList()159 void PasswordManagerHandler::SetPasswordList() {
160   ListValue entries;
161   bool show_passwords = *show_passwords_;
162   string16 empty;
163   for (size_t i = 0; i < password_list_.size(); ++i) {
164     ListValue* entry = new ListValue();
165     entry->Append(new StringValue(net::FormatUrl(password_list_[i]->origin,
166                                                  languages_)));
167     entry->Append(new StringValue(password_list_[i]->username_value));
168     entry->Append(new StringValue(
169         show_passwords ? password_list_[i]->password_value : empty));
170     entries.Append(entry);
171   }
172 
173   web_ui_->CallJavascriptFunction("PasswordManager.setSavedPasswordsList",
174                                   entries);
175 }
176 
SetPasswordExceptionList()177 void PasswordManagerHandler::SetPasswordExceptionList() {
178   ListValue entries;
179   for (size_t i = 0; i < password_exception_list_.size(); ++i) {
180     entries.Append(new StringValue(
181         net::FormatUrl(password_exception_list_[i]->origin, languages_)));
182   }
183 
184   web_ui_->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList",
185                                   entries);
186 }
187 
ListPopulater(PasswordManagerHandler * page)188 PasswordManagerHandler::ListPopulater::ListPopulater(
189     PasswordManagerHandler* page)
190     : page_(page),
191       pending_login_query_(0) {
192 }
193 
~ListPopulater()194 PasswordManagerHandler::ListPopulater::~ListPopulater() {
195 }
196 
PasswordListPopulater(PasswordManagerHandler * page)197 PasswordManagerHandler::PasswordListPopulater::PasswordListPopulater(
198     PasswordManagerHandler* page) : ListPopulater(page) {
199 }
200 
Populate()201 void PasswordManagerHandler::PasswordListPopulater::Populate() {
202   PasswordStore* store = page_->GetPasswordStore();
203   if (store != NULL) {
204     if (pending_login_query_)
205       store->CancelRequest(pending_login_query_);
206 
207     pending_login_query_ = store->GetAutofillableLogins(this);
208   } else {
209     LOG(ERROR) << "No password store! Cannot display passwords.";
210   }
211 }
212 
213 void PasswordManagerHandler::PasswordListPopulater::
OnPasswordStoreRequestDone(CancelableRequestProvider::Handle handle,const std::vector<webkit_glue::PasswordForm * > & result)214     OnPasswordStoreRequestDone(
215         CancelableRequestProvider::Handle handle,
216         const std::vector<webkit_glue::PasswordForm*>& result) {
217   DCHECK_EQ(pending_login_query_, handle);
218   pending_login_query_ = 0;
219   page_->password_list_.reset();
220   page_->password_list_.insert(page_->password_list_.end(),
221                                result.begin(), result.end());
222   page_->SetPasswordList();
223 }
224 
225 PasswordManagerHandler::PasswordExceptionListPopulater::
PasswordExceptionListPopulater(PasswordManagerHandler * page)226     PasswordExceptionListPopulater(PasswordManagerHandler* page)
227         : ListPopulater(page) {
228 }
229 
Populate()230 void PasswordManagerHandler::PasswordExceptionListPopulater::Populate() {
231   PasswordStore* store = page_->GetPasswordStore();
232   if (store != NULL) {
233     if (pending_login_query_)
234       store->CancelRequest(pending_login_query_);
235 
236     pending_login_query_ = store->GetBlacklistLogins(this);
237   } else {
238     LOG(ERROR) << "No password store! Cannot display exceptions.";
239   }
240 }
241 
242 void PasswordManagerHandler::PasswordExceptionListPopulater::
OnPasswordStoreRequestDone(CancelableRequestProvider::Handle handle,const std::vector<webkit_glue::PasswordForm * > & result)243     OnPasswordStoreRequestDone(
244         CancelableRequestProvider::Handle handle,
245         const std::vector<webkit_glue::PasswordForm*>& result) {
246   DCHECK_EQ(pending_login_query_, handle);
247   pending_login_query_ = 0;
248   page_->password_exception_list_.reset();
249   page_->password_exception_list_.insert(page_->password_exception_list_.end(),
250                                          result.begin(), result.end());
251   page_->SetPasswordExceptionList();
252 }
253