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