| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/autofill/content/renderer/password_generation_manager.h" | 5 #include "components/autofill/content/renderer/password_generation_manager.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "components/autofill/content/renderer/password_form_conversion_utils.h" | 9 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
| 10 #include "components/autofill/core/common/autofill_messages.h" | 10 #include "components/autofill/core/common/autofill_messages.h" |
| 11 #include "components/autofill/core/common/form_data.h" | 11 #include "components/autofill/core/common/form_data.h" |
| 12 #include "components/autofill/core/common/password_form.h" |
| 12 #include "components/autofill/core/common/password_generation_util.h" | 13 #include "components/autofill/core/common/password_generation_util.h" |
| 13 #include "content/public/renderer/render_view.h" | 14 #include "content/public/renderer/render_view.h" |
| 14 #include "google_apis/gaia/gaia_urls.h" | 15 #include "google_apis/gaia/gaia_urls.h" |
| 15 #include "third_party/WebKit/public/platform/WebCString.h" | 16 #include "third_party/WebKit/public/platform/WebCString.h" |
| 16 #include "third_party/WebKit/public/platform/WebRect.h" | 17 #include "third_party/WebKit/public/platform/WebRect.h" |
| 17 #include "third_party/WebKit/public/platform/WebVector.h" | 18 #include "third_party/WebKit/public/platform/WebVector.h" |
| 18 #include "third_party/WebKit/public/web/WebDocument.h" | 19 #include "third_party/WebKit/public/web/WebDocument.h" |
| 19 #include "third_party/WebKit/public/web/WebFormElement.h" | 20 #include "third_party/WebKit/public/web/WebFormElement.h" |
| 20 #include "third_party/WebKit/public/web/WebFrame.h" | 21 #include "third_party/WebKit/public/web/WebFrame.h" |
| 21 #include "third_party/WebKit/public/web/WebInputElement.h" | 22 #include "third_party/WebKit/public/web/WebInputElement.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 66 |
| 66 return false; | 67 return false; |
| 67 } | 68 } |
| 68 | 69 |
| 69 bool ContainsURL(const std::vector<GURL>& urls, const GURL& url) { | 70 bool ContainsURL(const std::vector<GURL>& urls, const GURL& url) { |
| 70 return std::find(urls.begin(), urls.end(), url) != urls.end(); | 71 return std::find(urls.begin(), urls.end(), url) != urls.end(); |
| 71 } | 72 } |
| 72 | 73 |
| 73 // Returns true if the |form1| is essentially equal to |form2|. | 74 // Returns true if the |form1| is essentially equal to |form2|. |
| 74 bool FormEquals(const autofill::FormData& form1, | 75 bool FormEquals(const autofill::FormData& form1, |
| 75 const content::PasswordForm& form2) { | 76 const PasswordForm& form2) { |
| 76 // TODO(zysxqn): use more signals than just origin to compare. | 77 // TODO(zysxqn): use more signals than just origin to compare. |
| 77 return form1.origin == form2.origin; | 78 return form1.origin == form2.origin; |
| 78 } | 79 } |
| 79 | 80 |
| 80 bool ContainsForm(const std::vector<autofill::FormData>& forms, | 81 bool ContainsForm(const std::vector<autofill::FormData>& forms, |
| 81 const content::PasswordForm& form) { | 82 const PasswordForm& form) { |
| 82 for (std::vector<autofill::FormData>::const_iterator it = | 83 for (std::vector<autofill::FormData>::const_iterator it = |
| 83 forms.begin(); it != forms.end(); ++it) { | 84 forms.begin(); it != forms.end(); ++it) { |
| 84 if (FormEquals(*it, form)) | 85 if (FormEquals(*it, form)) |
| 85 return true; | 86 return true; |
| 86 } | 87 } |
| 87 return false; | 88 return false; |
| 88 } | 89 } |
| 89 | 90 |
| 90 } // namespace | 91 } // namespace |
| 91 | 92 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 105 // hear back from the browser. We only clear this state on main frame load | 106 // hear back from the browser. We only clear this state on main frame load |
| 106 // as we don't want subframe loads to clear state that we have recieved from | 107 // as we don't want subframe loads to clear state that we have recieved from |
| 107 // the main frame. Note that we assume there is only one account creation | 108 // the main frame. Note that we assume there is only one account creation |
| 108 // form, but there could be multiple password forms in each frame. | 109 // form, but there could be multiple password forms in each frame. |
| 109 // | 110 // |
| 110 // TODO(zysxqn): Add stat when local heuristic fires but we don't show the | 111 // TODO(zysxqn): Add stat when local heuristic fires but we don't show the |
| 111 // password generation icon. | 112 // password generation icon. |
| 112 if (!frame->parent()) { | 113 if (!frame->parent()) { |
| 113 not_blacklisted_password_form_origins_.clear(); | 114 not_blacklisted_password_form_origins_.clear(); |
| 114 account_creation_forms_.clear(); | 115 account_creation_forms_.clear(); |
| 115 possible_account_creation_form_.reset(new content::PasswordForm()); | 116 possible_account_creation_form_.reset(new PasswordForm()); |
| 116 passwords_.clear(); | 117 passwords_.clear(); |
| 117 } | 118 } |
| 118 } | 119 } |
| 119 | 120 |
| 120 void PasswordGenerationManager::DidFinishLoad(WebKit::WebFrame* frame) { | 121 void PasswordGenerationManager::DidFinishLoad(WebKit::WebFrame* frame) { |
| 121 // We don't want to generate passwords if the browser won't store or sync | 122 // We don't want to generate passwords if the browser won't store or sync |
| 122 // them. | 123 // them. |
| 123 if (!enabled_) | 124 if (!enabled_) |
| 124 return; | 125 return; |
| 125 | 126 |
| 126 if (!ShouldAnalyzeDocument(frame->document())) | 127 if (!ShouldAnalyzeDocument(frame->document())) |
| 127 return; | 128 return; |
| 128 | 129 |
| 129 WebKit::WebVector<WebKit::WebFormElement> forms; | 130 WebKit::WebVector<WebKit::WebFormElement> forms; |
| 130 frame->document().forms(forms); | 131 frame->document().forms(forms); |
| 131 for (size_t i = 0; i < forms.size(); ++i) { | 132 for (size_t i = 0; i < forms.size(); ++i) { |
| 132 if (forms[i].isNull()) | 133 if (forms[i].isNull()) |
| 133 continue; | 134 continue; |
| 134 | 135 |
| 135 // If we can't get a valid PasswordForm, we skip this form because the | 136 // If we can't get a valid PasswordForm, we skip this form because the |
| 136 // the password won't get saved even if we generate it. | 137 // the password won't get saved even if we generate it. |
| 137 scoped_ptr<content::PasswordForm> password_form( | 138 scoped_ptr<PasswordForm> password_form( |
| 138 CreatePasswordForm(forms[i])); | 139 CreatePasswordForm(forms[i])); |
| 139 if (!password_form.get()) { | 140 if (!password_form.get()) { |
| 140 DVLOG(2) << "Skipping form as it would not be saved"; | 141 DVLOG(2) << "Skipping form as it would not be saved"; |
| 141 continue; | 142 continue; |
| 142 } | 143 } |
| 143 | 144 |
| 144 // Do not generate password for GAIA since it is used to retrieve the | 145 // Do not generate password for GAIA since it is used to retrieve the |
| 145 // generated paswords. | 146 // generated paswords. |
| 146 GURL realm(password_form->signon_realm); | 147 GURL realm(password_form->signon_realm); |
| 147 if (realm == GURL(GaiaUrls::GetInstance()->gaia_login_form_realm())) | 148 if (realm == GURL(GaiaUrls::GetInstance()->gaia_login_form_realm())) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 173 return false; | 174 return false; |
| 174 } | 175 } |
| 175 | 176 |
| 176 return true; | 177 return true; |
| 177 } | 178 } |
| 178 | 179 |
| 179 void PasswordGenerationManager::openPasswordGenerator( | 180 void PasswordGenerationManager::openPasswordGenerator( |
| 180 WebKit::WebInputElement& element) { | 181 WebKit::WebInputElement& element) { |
| 181 WebKit::WebElement button(element.passwordGeneratorButtonElement()); | 182 WebKit::WebElement button(element.passwordGeneratorButtonElement()); |
| 182 gfx::Rect rect(button.boundsInViewportSpace()); | 183 gfx::Rect rect(button.boundsInViewportSpace()); |
| 183 scoped_ptr<content::PasswordForm> password_form( | 184 scoped_ptr<PasswordForm> password_form( |
| 184 CreatePasswordForm(element.form())); | 185 CreatePasswordForm(element.form())); |
| 185 // We should not have shown the icon we can't create a valid PasswordForm. | 186 // We should not have shown the icon we can't create a valid PasswordForm. |
| 186 DCHECK(password_form.get()); | 187 DCHECK(password_form.get()); |
| 187 | 188 |
| 188 Send(new AutofillHostMsg_ShowPasswordGenerationPopup(routing_id(), | 189 Send(new AutofillHostMsg_ShowPasswordGenerationPopup(routing_id(), |
| 189 rect, | 190 rect, |
| 190 element.maxLength(), | 191 element.maxLength(), |
| 191 *password_form)); | 192 *password_form)); |
| 192 password_generation::LogPasswordGenerationEvent( | 193 password_generation::LogPasswordGenerationEvent( |
| 193 password_generation::BUBBLE_SHOWN); | 194 password_generation::BUBBLE_SHOWN); |
| 194 } | 195 } |
| 195 | 196 |
| 196 bool PasswordGenerationManager::OnMessageReceived(const IPC::Message& message) { | 197 bool PasswordGenerationManager::OnMessageReceived(const IPC::Message& message) { |
| 197 bool handled = true; | 198 bool handled = true; |
| 198 IPC_BEGIN_MESSAGE_MAP(PasswordGenerationManager, message) | 199 IPC_BEGIN_MESSAGE_MAP(PasswordGenerationManager, message) |
| 199 IPC_MESSAGE_HANDLER(AutofillMsg_FormNotBlacklisted, | 200 IPC_MESSAGE_HANDLER(AutofillMsg_FormNotBlacklisted, |
| 200 OnFormNotBlacklisted) | 201 OnFormNotBlacklisted) |
| 201 IPC_MESSAGE_HANDLER(AutofillMsg_GeneratedPasswordAccepted, | 202 IPC_MESSAGE_HANDLER(AutofillMsg_GeneratedPasswordAccepted, |
| 202 OnPasswordAccepted) | 203 OnPasswordAccepted) |
| 203 IPC_MESSAGE_HANDLER(AutofillMsg_PasswordGenerationEnabled, | 204 IPC_MESSAGE_HANDLER(AutofillMsg_PasswordGenerationEnabled, |
| 204 OnPasswordGenerationEnabled) | 205 OnPasswordGenerationEnabled) |
| 205 IPC_MESSAGE_HANDLER(AutofillMsg_AccountCreationFormsDetected, | 206 IPC_MESSAGE_HANDLER(AutofillMsg_AccountCreationFormsDetected, |
| 206 OnAccountCreationFormsDetected) | 207 OnAccountCreationFormsDetected) |
| 207 IPC_MESSAGE_UNHANDLED(handled = false) | 208 IPC_MESSAGE_UNHANDLED(handled = false) |
| 208 IPC_END_MESSAGE_MAP() | 209 IPC_END_MESSAGE_MAP() |
| 209 return handled; | 210 return handled; |
| 210 } | 211 } |
| 211 | 212 |
| 212 void PasswordGenerationManager::OnFormNotBlacklisted( | 213 void PasswordGenerationManager::OnFormNotBlacklisted(const PasswordForm& form) { |
| 213 const content::PasswordForm& form) { | |
| 214 not_blacklisted_password_form_origins_.push_back(form.origin); | 214 not_blacklisted_password_form_origins_.push_back(form.origin); |
| 215 MaybeShowIcon(); | 215 MaybeShowIcon(); |
| 216 } | 216 } |
| 217 | 217 |
| 218 void PasswordGenerationManager::OnPasswordAccepted( | 218 void PasswordGenerationManager::OnPasswordAccepted( |
| 219 const base::string16& password) { | 219 const base::string16& password) { |
| 220 for (std::vector<WebKit::WebInputElement>::iterator it = passwords_.begin(); | 220 for (std::vector<WebKit::WebInputElement>::iterator it = passwords_.begin(); |
| 221 it != passwords_.end(); ++it) { | 221 it != passwords_.end(); ++it) { |
| 222 it->setValue(password); | 222 it->setValue(password); |
| 223 it->setAutofilled(true); | 223 it->setAutofilled(true); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 return; | 260 return; |
| 261 } | 261 } |
| 262 | 262 |
| 263 passwords_[0].passwordGeneratorButtonElement().setAttribute("style", | 263 passwords_[0].passwordGeneratorButtonElement().setAttribute("style", |
| 264 "display:block"); | 264 "display:block"); |
| 265 password_generation::LogPasswordGenerationEvent( | 265 password_generation::LogPasswordGenerationEvent( |
| 266 password_generation::ICON_SHOWN); | 266 password_generation::ICON_SHOWN); |
| 267 } | 267 } |
| 268 | 268 |
| 269 } // namespace autofill | 269 } // namespace autofill |
| OLD | NEW |