| 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_agent.h" | 5 #include "components/autofill/content/renderer/password_generation_agent.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "components/autofill/content/renderer/password_form_conversion_utils.h" | 10 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "third_party/WebKit/public/web/WebView.h" | 26 #include "third_party/WebKit/public/web/WebView.h" |
| 27 #include "ui/gfx/rect.h" | 27 #include "ui/gfx/rect.h" |
| 28 | 28 |
| 29 namespace autofill { | 29 namespace autofill { |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 // Returns true if we think that this form is for account creation. |passwords| | 33 // Returns true if we think that this form is for account creation. |passwords| |
| 34 // is filled with the password field(s) in the form. | 34 // is filled with the password field(s) in the form. |
| 35 bool GetAccountCreationPasswordFields( | 35 bool GetAccountCreationPasswordFields( |
| 36 const WebKit::WebFormElement& form, | 36 const blink::WebFormElement& form, |
| 37 std::vector<WebKit::WebInputElement>* passwords) { | 37 std::vector<blink::WebInputElement>* passwords) { |
| 38 // Grab all of the passwords for the form. | 38 // Grab all of the passwords for the form. |
| 39 WebKit::WebVector<WebKit::WebFormControlElement> control_elements; | 39 blink::WebVector<blink::WebFormControlElement> control_elements; |
| 40 form.getFormControlElements(control_elements); | 40 form.getFormControlElements(control_elements); |
| 41 | 41 |
| 42 size_t num_input_elements = 0; | 42 size_t num_input_elements = 0; |
| 43 for (size_t i = 0; i < control_elements.size(); i++) { | 43 for (size_t i = 0; i < control_elements.size(); i++) { |
| 44 WebKit::WebInputElement* input_element = | 44 blink::WebInputElement* input_element = |
| 45 toWebInputElement(&control_elements[i]); | 45 toWebInputElement(&control_elements[i]); |
| 46 // Only pay attention to visible password fields. | 46 // Only pay attention to visible password fields. |
| 47 if (input_element && | 47 if (input_element && |
| 48 input_element->isTextField() && | 48 input_element->isTextField() && |
| 49 input_element->hasNonEmptyBoundingBox()) { | 49 input_element->hasNonEmptyBoundingBox()) { |
| 50 num_input_elements++; | 50 num_input_elements++; |
| 51 if (input_element->isPasswordField()) | 51 if (input_element->isPasswordField()) |
| 52 passwords->push_back(*input_element); | 52 passwords->push_back(*input_element); |
| 53 } | 53 } |
| 54 } | 54 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 } // namespace | 96 } // namespace |
| 97 | 97 |
| 98 PasswordGenerationAgent::PasswordGenerationAgent( | 98 PasswordGenerationAgent::PasswordGenerationAgent( |
| 99 content::RenderView* render_view) | 99 content::RenderView* render_view) |
| 100 : content::RenderViewObserver(render_view), | 100 : content::RenderViewObserver(render_view), |
| 101 render_view_(render_view) { | 101 render_view_(render_view) { |
| 102 render_view_->GetWebView()->setPasswordGeneratorClient(this); | 102 render_view_->GetWebView()->setPasswordGeneratorClient(this); |
| 103 } | 103 } |
| 104 PasswordGenerationAgent::~PasswordGenerationAgent() {} | 104 PasswordGenerationAgent::~PasswordGenerationAgent() {} |
| 105 | 105 |
| 106 void PasswordGenerationAgent::DidFinishDocumentLoad(WebKit::WebFrame* frame) { | 106 void PasswordGenerationAgent::DidFinishDocumentLoad(blink::WebFrame* frame) { |
| 107 // In every navigation, the IPC message sent by the password autofill manager | 107 // In every navigation, the IPC message sent by the password autofill manager |
| 108 // to query whether the current form is blacklisted or not happens when the | 108 // to query whether the current form is blacklisted or not happens when the |
| 109 // document load finishes, so we need to clear previous states here before we | 109 // document load finishes, so we need to clear previous states here before we |
| 110 // hear back from the browser. We only clear this state on main frame load | 110 // hear back from the browser. We only clear this state on main frame load |
| 111 // as we don't want subframe loads to clear state that we have recieved from | 111 // as we don't want subframe loads to clear state that we have recieved from |
| 112 // the main frame. Note that we assume there is only one account creation | 112 // the main frame. Note that we assume there is only one account creation |
| 113 // form, but there could be multiple password forms in each frame. | 113 // form, but there could be multiple password forms in each frame. |
| 114 // | 114 // |
| 115 // TODO(zysxqn): Add stat when local heuristic fires but we don't show the | 115 // TODO(zysxqn): Add stat when local heuristic fires but we don't show the |
| 116 // password generation icon. | 116 // password generation icon. |
| 117 if (!frame->parent()) { | 117 if (!frame->parent()) { |
| 118 not_blacklisted_password_form_origins_.clear(); | 118 not_blacklisted_password_form_origins_.clear(); |
| 119 generation_enabled_forms_.clear(); | 119 generation_enabled_forms_.clear(); |
| 120 possible_account_creation_form_.reset(new PasswordForm()); | 120 possible_account_creation_form_.reset(new PasswordForm()); |
| 121 passwords_.clear(); | 121 passwords_.clear(); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 void PasswordGenerationAgent::DidFinishLoad(WebKit::WebFrame* frame) { | 125 void PasswordGenerationAgent::DidFinishLoad(blink::WebFrame* frame) { |
| 126 // We don't want to generate passwords if the browser won't store or sync | 126 // We don't want to generate passwords if the browser won't store or sync |
| 127 // them. | 127 // them. |
| 128 if (!ShouldAnalyzeDocument(frame->document())) | 128 if (!ShouldAnalyzeDocument(frame->document())) |
| 129 return; | 129 return; |
| 130 | 130 |
| 131 WebKit::WebVector<WebKit::WebFormElement> forms; | 131 blink::WebVector<blink::WebFormElement> forms; |
| 132 frame->document().forms(forms); | 132 frame->document().forms(forms); |
| 133 for (size_t i = 0; i < forms.size(); ++i) { | 133 for (size_t i = 0; i < forms.size(); ++i) { |
| 134 if (forms[i].isNull()) | 134 if (forms[i].isNull()) |
| 135 continue; | 135 continue; |
| 136 | 136 |
| 137 // If we can't get a valid PasswordForm, we skip this form because the | 137 // If we can't get a valid PasswordForm, we skip this form because the |
| 138 // the password won't get saved even if we generate it. | 138 // the password won't get saved even if we generate it. |
| 139 scoped_ptr<PasswordForm> password_form( | 139 scoped_ptr<PasswordForm> password_form( |
| 140 CreatePasswordForm(forms[i])); | 140 CreatePasswordForm(forms[i])); |
| 141 if (!password_form.get()) { | 141 if (!password_form.get()) { |
| 142 DVLOG(2) << "Skipping form as it would not be saved"; | 142 DVLOG(2) << "Skipping form as it would not be saved"; |
| 143 continue; | 143 continue; |
| 144 } | 144 } |
| 145 | 145 |
| 146 // Do not generate password for GAIA since it is used to retrieve the | 146 // Do not generate password for GAIA since it is used to retrieve the |
| 147 // generated paswords. | 147 // generated paswords. |
| 148 GURL realm(password_form->signon_realm); | 148 GURL realm(password_form->signon_realm); |
| 149 if (realm == GaiaUrls::GetInstance()->gaia_login_form_realm()) | 149 if (realm == GaiaUrls::GetInstance()->gaia_login_form_realm()) |
| 150 continue; | 150 continue; |
| 151 | 151 |
| 152 std::vector<WebKit::WebInputElement> passwords; | 152 std::vector<blink::WebInputElement> passwords; |
| 153 if (GetAccountCreationPasswordFields(forms[i], &passwords)) { | 153 if (GetAccountCreationPasswordFields(forms[i], &passwords)) { |
| 154 DVLOG(2) << "Account creation form detected"; | 154 DVLOG(2) << "Account creation form detected"; |
| 155 password_generation::LogPasswordGenerationEvent( | 155 password_generation::LogPasswordGenerationEvent( |
| 156 password_generation::SIGN_UP_DETECTED); | 156 password_generation::SIGN_UP_DETECTED); |
| 157 passwords_ = passwords; | 157 passwords_ = passwords; |
| 158 possible_account_creation_form_.swap(password_form); | 158 possible_account_creation_form_.swap(password_form); |
| 159 MaybeShowIcon(); | 159 MaybeShowIcon(); |
| 160 // We assume that there is only one account creation field per URL. | 160 // We assume that there is only one account creation field per URL. |
| 161 return; | 161 return; |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 password_generation::LogPasswordGenerationEvent( | 164 password_generation::LogPasswordGenerationEvent( |
| 165 password_generation::NO_SIGN_UP_DETECTED); | 165 password_generation::NO_SIGN_UP_DETECTED); |
| 166 } | 166 } |
| 167 | 167 |
| 168 bool PasswordGenerationAgent::ShouldAnalyzeDocument( | 168 bool PasswordGenerationAgent::ShouldAnalyzeDocument( |
| 169 const WebKit::WebDocument& document) const { | 169 const blink::WebDocument& document) const { |
| 170 // Make sure that this security origin is allowed to use password manager. | 170 // Make sure that this security origin is allowed to use password manager. |
| 171 // Generating a password that can't be saved is a bad idea. | 171 // Generating a password that can't be saved is a bad idea. |
| 172 WebKit::WebSecurityOrigin origin = document.securityOrigin(); | 172 blink::WebSecurityOrigin origin = document.securityOrigin(); |
| 173 if (!origin.canAccessPasswordManager()) { | 173 if (!origin.canAccessPasswordManager()) { |
| 174 DVLOG(1) << "No PasswordManager access"; | 174 DVLOG(1) << "No PasswordManager access"; |
| 175 return false; | 175 return false; |
| 176 } | 176 } |
| 177 | 177 |
| 178 return true; | 178 return true; |
| 179 } | 179 } |
| 180 | 180 |
| 181 void PasswordGenerationAgent::openPasswordGenerator( | 181 void PasswordGenerationAgent::openPasswordGenerator( |
| 182 WebKit::WebInputElement& element) { | 182 blink::WebInputElement& element) { |
| 183 WebKit::WebElement button(element.passwordGeneratorButtonElement()); | 183 blink::WebElement button(element.passwordGeneratorButtonElement()); |
| 184 gfx::Rect rect(button.boundsInViewportSpace()); | 184 gfx::Rect rect(button.boundsInViewportSpace()); |
| 185 scoped_ptr<PasswordForm> password_form( | 185 scoped_ptr<PasswordForm> password_form( |
| 186 CreatePasswordForm(element.form())); | 186 CreatePasswordForm(element.form())); |
| 187 // We should not have shown the icon we can't create a valid PasswordForm. | 187 // We should not have shown the icon we can't create a valid PasswordForm. |
| 188 DCHECK(password_form.get()); | 188 DCHECK(password_form.get()); |
| 189 | 189 |
| 190 Send(new AutofillHostMsg_ShowPasswordGenerationPopup(routing_id(), | 190 Send(new AutofillHostMsg_ShowPasswordGenerationPopup(routing_id(), |
| 191 rect, | 191 rect, |
| 192 element.maxLength(), | 192 element.maxLength(), |
| 193 *password_form)); | 193 *password_form)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 209 return handled; | 209 return handled; |
| 210 } | 210 } |
| 211 | 211 |
| 212 void PasswordGenerationAgent::OnFormNotBlacklisted(const PasswordForm& form) { | 212 void PasswordGenerationAgent::OnFormNotBlacklisted(const PasswordForm& form) { |
| 213 not_blacklisted_password_form_origins_.push_back(form.origin); | 213 not_blacklisted_password_form_origins_.push_back(form.origin); |
| 214 MaybeShowIcon(); | 214 MaybeShowIcon(); |
| 215 } | 215 } |
| 216 | 216 |
| 217 void PasswordGenerationAgent::OnPasswordAccepted( | 217 void PasswordGenerationAgent::OnPasswordAccepted( |
| 218 const base::string16& password) { | 218 const base::string16& password) { |
| 219 for (std::vector<WebKit::WebInputElement>::iterator it = passwords_.begin(); | 219 for (std::vector<blink::WebInputElement>::iterator it = passwords_.begin(); |
| 220 it != passwords_.end(); ++it) { | 220 it != passwords_.end(); ++it) { |
| 221 it->setValue(password); | 221 it->setValue(password); |
| 222 it->setAutofilled(true); | 222 it->setAutofilled(true); |
| 223 // Advance focus to the next input field. We assume password fields in | 223 // Advance focus to the next input field. We assume password fields in |
| 224 // an account creation form are always adjacent. | 224 // an account creation form are always adjacent. |
| 225 render_view_->GetWebView()->advanceFocus(false); | 225 render_view_->GetWebView()->advanceFocus(false); |
| 226 } | 226 } |
| 227 } | 227 } |
| 228 | 228 |
| 229 void PasswordGenerationAgent::OnAccountCreationFormsDetected( | 229 void PasswordGenerationAgent::OnAccountCreationFormsDetected( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 return; | 265 return; |
| 266 } | 266 } |
| 267 | 267 |
| 268 passwords_[0].passwordGeneratorButtonElement().setAttribute("style", | 268 passwords_[0].passwordGeneratorButtonElement().setAttribute("style", |
| 269 "display:block"); | 269 "display:block"); |
| 270 password_generation::LogPasswordGenerationEvent( | 270 password_generation::LogPasswordGenerationEvent( |
| 271 password_generation::ICON_SHOWN); | 271 password_generation::ICON_SHOWN); |
| 272 } | 272 } |
| 273 | 273 |
| 274 } // namespace autofill | 274 } // namespace autofill |
| OLD | NEW |