OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/webui/options/password_manager_handler.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/string_number_conversions.h" | |
9 #include "base/utf_string_conversions.h" | |
10 #include "base/values.h" | |
11 #include "chrome/browser/password_manager/password_store_factory.h" | |
12 #include "chrome/browser/prefs/pref_service.h" | |
13 #include "chrome/browser/profiles/profile.h" | |
14 #include "chrome/common/chrome_notification_types.h" | |
15 #include "chrome/common/pref_names.h" | |
16 #include "chrome/common/url_constants.h" | |
17 #include "content/public/browser/notification_details.h" | |
18 #include "content/public/browser/notification_source.h" | |
19 #include "content/public/browser/web_ui.h" | |
20 #include "grit/chromium_strings.h" | |
21 #include "grit/generated_resources.h" | |
22 #include "net/base/net_util.h" | |
23 #include "ui/base/l10n/l10n_util.h" | |
24 #include "webkit/forms/password_form.h" | |
25 | |
26 PasswordManagerHandler::PasswordManagerHandler() | |
27 : ALLOW_THIS_IN_INITIALIZER_LIST(populater_(this)), | |
28 ALLOW_THIS_IN_INITIALIZER_LIST(exception_populater_(this)) { | |
29 } | |
30 | |
31 PasswordManagerHandler::~PasswordManagerHandler() { | |
32 PasswordStore* store = GetPasswordStore(); | |
33 if (store) | |
34 store->RemoveObserver(this); | |
35 } | |
36 | |
37 void PasswordManagerHandler::GetLocalizedValues( | |
38 DictionaryValue* localized_strings) { | |
39 DCHECK(localized_strings); | |
40 | |
41 static const OptionsStringResource resources[] = { | |
42 { "savedPasswordsTitle", | |
43 IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE }, | |
44 { "passwordExceptionsTitle", | |
45 IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE }, | |
46 { "passwordSearchPlaceholder", | |
47 IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS }, | |
48 { "passwordShowButton", | |
49 IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON }, | |
50 { "passwordHideButton", | |
51 IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON }, | |
52 { "passwordsSiteColumn", | |
53 IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN }, | |
54 { "passwordsUsernameColumn", | |
55 IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN }, | |
56 { "passwordsRemoveButton", | |
57 IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON }, | |
58 { "passwordsNoPasswordsDescription", | |
59 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION }, | |
60 { "passwordsNoExceptionsDescription", | |
61 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION }, | |
62 { "passwordsRemoveAllButton", | |
63 IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON }, | |
64 { "passwordsRemoveAllTitle", | |
65 IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS }, | |
66 { "passwordsRemoveAllWarning", | |
67 IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS }, | |
68 }; | |
69 | |
70 RegisterStrings(localized_strings, resources, arraysize(resources)); | |
71 RegisterTitle(localized_strings, "passwordsPage", | |
72 IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE); | |
73 | |
74 localized_strings->SetString("passwordManagerLearnMoreURL", | |
75 chrome::kPasswordManagerLearnMoreURL); | |
76 } | |
77 | |
78 void PasswordManagerHandler::InitializeHandler() { | |
79 // Due to the way that handlers are (re)initialized under certain types of | |
80 // navigation, we may already be initialized. (See bugs 88986 and 86448.) | |
81 // If this is the case, return immediately. This is a hack. | |
82 // TODO(mdm): remove this hack once it is no longer necessary. | |
83 if (!show_passwords_.GetPrefName().empty()) | |
84 return; | |
85 | |
86 show_passwords_.Init(prefs::kPasswordManagerAllowShowPasswords, | |
87 Profile::FromWebUI(web_ui())->GetPrefs(), this); | |
88 // We should not cache web_ui()->GetProfile(). See crosbug.com/6304. | |
89 PasswordStore* store = GetPasswordStore(); | |
90 if (store) | |
91 store->AddObserver(this); | |
92 } | |
93 | |
94 void PasswordManagerHandler::RegisterMessages() { | |
95 web_ui()->RegisterMessageCallback("updatePasswordLists", | |
96 base::Bind(&PasswordManagerHandler::UpdatePasswordLists, | |
97 base::Unretained(this))); | |
98 web_ui()->RegisterMessageCallback("removeSavedPassword", | |
99 base::Bind(&PasswordManagerHandler::RemoveSavedPassword, | |
100 base::Unretained(this))); | |
101 web_ui()->RegisterMessageCallback("removePasswordException", | |
102 base::Bind(&PasswordManagerHandler::RemovePasswordException, | |
103 base::Unretained(this))); | |
104 web_ui()->RegisterMessageCallback("removeAllSavedPasswords", | |
105 base::Bind(&PasswordManagerHandler::RemoveAllSavedPasswords, | |
106 base::Unretained(this))); | |
107 web_ui()->RegisterMessageCallback("removeAllPasswordExceptions", | |
108 base::Bind(&PasswordManagerHandler::RemoveAllPasswordExceptions, | |
109 base::Unretained(this))); | |
110 } | |
111 | |
112 void PasswordManagerHandler::OnLoginsChanged() { | |
113 UpdatePasswordLists(NULL); | |
114 } | |
115 | |
116 PasswordStore* PasswordManagerHandler::GetPasswordStore() { | |
117 return PasswordStoreFactory::GetForProfile( | |
118 Profile::FromWebUI(web_ui()), | |
119 Profile::EXPLICIT_ACCESS); | |
120 } | |
121 | |
122 void PasswordManagerHandler::Observe( | |
123 int type, | |
124 const content::NotificationSource& source, | |
125 const content::NotificationDetails& details) { | |
126 if (type == chrome::NOTIFICATION_PREF_CHANGED) { | |
127 std::string* pref_name = content::Details<std::string>(details).ptr(); | |
128 if (*pref_name == prefs::kPasswordManagerAllowShowPasswords) { | |
129 UpdatePasswordLists(NULL); | |
130 } | |
131 } | |
132 | |
133 OptionsPageUIHandler::Observe(type, source, details); | |
134 } | |
135 | |
136 void PasswordManagerHandler::UpdatePasswordLists(const ListValue* args) { | |
137 // Reset the current lists. | |
138 password_list_.reset(); | |
139 password_exception_list_.reset(); | |
140 | |
141 languages_ = Profile::FromWebUI(web_ui())->GetPrefs()-> | |
142 GetString(prefs::kAcceptLanguages); | |
143 populater_.Populate(); | |
144 exception_populater_.Populate(); | |
145 } | |
146 | |
147 void PasswordManagerHandler::RemoveSavedPassword(const ListValue* args) { | |
148 PasswordStore* store = GetPasswordStore(); | |
149 if (!store) | |
150 return; | |
151 std::string string_value = UTF16ToUTF8(ExtractStringValue(args)); | |
152 int index; | |
153 if (base::StringToInt(string_value, &index) && index >= 0 && | |
154 static_cast<size_t>(index) < password_list_.size()) | |
155 store->RemoveLogin(*password_list_[index]); | |
156 } | |
157 | |
158 void PasswordManagerHandler::RemovePasswordException( | |
159 const ListValue* args) { | |
160 PasswordStore* store = GetPasswordStore(); | |
161 if (!store) | |
162 return; | |
163 std::string string_value = UTF16ToUTF8(ExtractStringValue(args)); | |
164 int index; | |
165 if (base::StringToInt(string_value, &index) && index >= 0 && | |
166 static_cast<size_t>(index) < password_exception_list_.size()) | |
167 store->RemoveLogin(*password_exception_list_[index]); | |
168 } | |
169 | |
170 void PasswordManagerHandler::RemoveAllSavedPasswords( | |
171 const ListValue* args) { | |
172 // TODO(jhawkins): This will cause a list refresh for every password in the | |
173 // list. Add PasswordStore::RemoveAllLogins(). | |
174 PasswordStore* store = GetPasswordStore(); | |
175 if (!store) | |
176 return; | |
177 for (size_t i = 0; i < password_list_.size(); ++i) | |
178 store->RemoveLogin(*password_list_[i]); | |
179 } | |
180 | |
181 void PasswordManagerHandler::RemoveAllPasswordExceptions( | |
182 const ListValue* args) { | |
183 PasswordStore* store = GetPasswordStore(); | |
184 if (!store) | |
185 return; | |
186 for (size_t i = 0; i < password_exception_list_.size(); ++i) | |
187 store->RemoveLogin(*password_exception_list_[i]); | |
188 } | |
189 | |
190 void PasswordManagerHandler::SetPasswordList() { | |
191 // Due to the way that handlers are (re)initialized under certain types of | |
192 // navigation, we may not be initialized yet. (See bugs 88986 and 86448.) | |
193 // If this is the case, initialize on demand. This is a hack. | |
194 // TODO(mdm): remove this hack once it is no longer necessary. | |
195 if (show_passwords_.GetPrefName().empty()) | |
196 InitializeHandler(); | |
197 | |
198 ListValue entries; | |
199 bool show_passwords = *show_passwords_; | |
200 string16 empty; | |
201 for (size_t i = 0; i < password_list_.size(); ++i) { | |
202 ListValue* entry = new ListValue(); | |
203 entry->Append(new StringValue(net::FormatUrl(password_list_[i]->origin, | |
204 languages_))); | |
205 entry->Append(new StringValue(password_list_[i]->username_value)); | |
206 entry->Append(new StringValue( | |
207 show_passwords ? password_list_[i]->password_value : empty)); | |
208 entries.Append(entry); | |
209 } | |
210 | |
211 web_ui()->CallJavascriptFunction("PasswordManager.setSavedPasswordsList", | |
212 entries); | |
213 } | |
214 | |
215 void PasswordManagerHandler::SetPasswordExceptionList() { | |
216 ListValue entries; | |
217 for (size_t i = 0; i < password_exception_list_.size(); ++i) { | |
218 entries.Append(new StringValue( | |
219 net::FormatUrl(password_exception_list_[i]->origin, languages_))); | |
220 } | |
221 | |
222 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList", | |
223 entries); | |
224 } | |
225 | |
226 PasswordManagerHandler::ListPopulater::ListPopulater( | |
227 PasswordManagerHandler* page) | |
228 : page_(page), | |
229 pending_login_query_(0) { | |
230 } | |
231 | |
232 PasswordManagerHandler::ListPopulater::~ListPopulater() { | |
233 } | |
234 | |
235 PasswordManagerHandler::PasswordListPopulater::PasswordListPopulater( | |
236 PasswordManagerHandler* page) : ListPopulater(page) { | |
237 } | |
238 | |
239 void PasswordManagerHandler::PasswordListPopulater::Populate() { | |
240 PasswordStore* store = page_->GetPasswordStore(); | |
241 if (store != NULL) { | |
242 if (pending_login_query_) | |
243 store->CancelRequest(pending_login_query_); | |
244 | |
245 pending_login_query_ = store->GetAutofillableLogins(this); | |
246 } else { | |
247 LOG(ERROR) << "No password store! Cannot display passwords."; | |
248 } | |
249 } | |
250 | |
251 void PasswordManagerHandler::PasswordListPopulater:: | |
252 OnPasswordStoreRequestDone( | |
253 CancelableRequestProvider::Handle handle, | |
254 const std::vector<webkit::forms::PasswordForm*>& result) { | |
255 DCHECK_EQ(pending_login_query_, handle); | |
256 pending_login_query_ = 0; | |
257 page_->password_list_.reset(); | |
258 page_->password_list_.insert(page_->password_list_.end(), | |
259 result.begin(), result.end()); | |
260 page_->SetPasswordList(); | |
261 } | |
262 | |
263 PasswordManagerHandler::PasswordExceptionListPopulater:: | |
264 PasswordExceptionListPopulater(PasswordManagerHandler* page) | |
265 : ListPopulater(page) { | |
266 } | |
267 | |
268 void PasswordManagerHandler::PasswordExceptionListPopulater::Populate() { | |
269 PasswordStore* store = page_->GetPasswordStore(); | |
270 if (store != NULL) { | |
271 if (pending_login_query_) | |
272 store->CancelRequest(pending_login_query_); | |
273 | |
274 pending_login_query_ = store->GetBlacklistLogins(this); | |
275 } else { | |
276 LOG(ERROR) << "No password store! Cannot display exceptions."; | |
277 } | |
278 } | |
279 | |
280 void PasswordManagerHandler::PasswordExceptionListPopulater:: | |
281 OnPasswordStoreRequestDone( | |
282 CancelableRequestProvider::Handle handle, | |
283 const std::vector<webkit::forms::PasswordForm*>& result) { | |
284 DCHECK_EQ(pending_login_query_, handle); | |
285 pending_login_query_ = 0; | |
286 page_->password_exception_list_.reset(); | |
287 page_->password_exception_list_.insert(page_->password_exception_list_.end(), | |
288 result.begin(), result.end()); | |
289 page_->SetPasswordExceptionList(); | |
290 } | |
OLD | NEW |