Commit d0e6cc4b authored by Vadym Doroshenko's avatar Vadym Doroshenko Committed by Commit Bot

Adding class NewPasswordFormManager.

This CL adds class NewPasswordFormManager as part of Password Manager
redesigning go/new-cpm-design-refactoring. Now this class has very
basic functionality. NewPasswordFormManager is aimed to replace
PasswordFormManager

Bug: 831123
Change-Id: Idd5e0e477ce939407c4c85dd49eb19412b098d04
Reviewed-on: https://chromium-review.googlesource.com/1012838
Commit-Queue: Vadym Doroshenko <dvadym@chromium.org>
Reviewed-by: default avatarVaclav Brozek <vabr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551707}
parent 1ef25cff
...@@ -81,6 +81,8 @@ static_library("browser") { ...@@ -81,6 +81,8 @@ static_library("browser") {
"login_database_win.cc", "login_database_win.cc",
"login_model.cc", "login_model.cc",
"login_model.h", "login_model.h",
"new_password_form_manager.cc",
"new_password_form_manager.h",
"password_autofill_manager.cc", "password_autofill_manager.cc",
"password_autofill_manager.h", "password_autofill_manager.h",
"password_bubble_experiment.cc", "password_bubble_experiment.cc",
...@@ -346,6 +348,7 @@ source_set("unit_tests") { ...@@ -346,6 +348,7 @@ source_set("unit_tests") {
"log_router_unittest.cc", "log_router_unittest.cc",
"login_database_unittest.cc", "login_database_unittest.cc",
"login_model_unittest.cc", "login_model_unittest.cc",
"new_password_form_manager_unittest.cc",
"password_autofill_manager_unittest.cc", "password_autofill_manager_unittest.cc",
"password_bubble_experiment_unittest.cc", "password_bubble_experiment_unittest.cc",
"password_form_manager_unittest.cc", "password_form_manager_unittest.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/new_password_form_manager.h"
using autofill::FormData;
namespace password_manager {
NewPasswordFormManager::NewPasswordFormManager(
const autofill::FormData& observed_form)
: observed_form_(observed_form) {}
NewPasswordFormManager::~NewPasswordFormManager() = default;
bool NewPasswordFormManager::DoesManage(const autofill::FormData& form) const {
return observed_form_.SameFormAs(form);
}
} // namespace password_manager
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_NEW_PASSWORD_FORM_MANAGER_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_NEW_PASSWORD_FORM_MANAGER_H_
#include "base/macros.h"
#include "components/autofill/core/common/form_data.h"
namespace password_manager {
// This class helps with filling the observed form and with saving/updating the
// stored information about it. It is aimed to replace PasswordFormManager and
// to be renamed in new Password Manager design. Details
// go/new-cpm-design-refactoring.
class NewPasswordFormManager {
public:
explicit NewPasswordFormManager(const autofill::FormData& observed_form);
~NewPasswordFormManager();
// Compares |observed_form_| with |form| and returns true if they are the
// same.
bool DoesManage(const autofill::FormData& form) const;
private:
const autofill::FormData observed_form_;
DISALLOW_COPY_AND_ASSIGN(NewPasswordFormManager);
};
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_NEW_PASSWORD_FORM_MANAGER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/new_password_form_manager.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/form_data.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using autofill::FormData;
using autofill::FormFieldData;
using base::ASCIIToUTF16;
namespace password_manager {
class NewPasswordFormManagerTest : public testing::Test {
public:
NewPasswordFormManagerTest() {
form_.name = ASCIIToUTF16("sign-in");
FormFieldData field;
field.name = ASCIIToUTF16("firstname");
field.form_control_type = "text";
form_.fields.push_back(field);
field.name = ASCIIToUTF16("username");
field.form_control_type = "text";
form_.fields.push_back(field);
field.name = ASCIIToUTF16("password");
field.form_control_type = "password";
form_.fields.push_back(field);
}
protected:
FormData form_;
};
TEST_F(NewPasswordFormManagerTest, DoesManage) {
NewPasswordFormManager form_manager(form_);
EXPECT_TRUE(form_manager.DoesManage(form_));
FormData another_form = form_;
another_form.name += ASCIIToUTF16("1");
EXPECT_FALSE(form_manager.DoesManage(another_form));
another_form = form_;
another_form.fields[0].name += ASCIIToUTF16("1");
EXPECT_FALSE(form_manager.DoesManage(another_form));
}
} // namespace password_manager
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "components/password_manager/core/browser/form_saver_impl.h" #include "components/password_manager/core/browser/form_saver_impl.h"
#include "components/password_manager/core/browser/keychain_migration_status_mac.h" #include "components/password_manager/core/browser/keychain_migration_status_mac.h"
#include "components/password_manager/core/browser/log_manager.h" #include "components/password_manager/core/browser/log_manager.h"
#include "components/password_manager/core/browser/new_password_form_manager.h"
#include "components/password_manager/core/browser/password_autofill_manager.h" #include "components/password_manager/core/browser/password_autofill_manager.h"
#include "components/password_manager/core/browser/password_form_manager.h" #include "components/password_manager/core/browser/password_form_manager.h"
#include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_client.h"
...@@ -447,6 +448,7 @@ void PasswordManager::UpdateFormManagers() { ...@@ -447,6 +448,7 @@ void PasswordManager::UpdateFormManagers() {
void PasswordManager::DropFormManagers() { void PasswordManager::DropFormManagers() {
pending_login_managers_.clear(); pending_login_managers_.clear();
form_managers_.clear();
provisional_save_manager_.reset(); provisional_save_manager_.reset();
all_visible_forms_.clear(); all_visible_forms_.clear();
} }
...@@ -482,6 +484,7 @@ void PasswordManager::RemoveObserver(LoginModelObserver* observer) { ...@@ -482,6 +484,7 @@ void PasswordManager::RemoveObserver(LoginModelObserver* observer) {
void PasswordManager::DidNavigateMainFrame() { void PasswordManager::DidNavigateMainFrame() {
entry_to_check_ = NavigationEntryToCheck::LAST_COMMITTED; entry_to_check_ = NavigationEntryToCheck::LAST_COMMITTED;
pending_login_managers_.clear(); pending_login_managers_.clear();
form_managers_.clear();
} }
void PasswordManager::OnPasswordFormSubmitted( void PasswordManager::OnPasswordFormSubmitted(
...@@ -572,6 +575,11 @@ void PasswordManager::CreatePendingLoginManagers( ...@@ -572,6 +575,11 @@ void PasswordManager::CreatePendingLoginManagers(
logger->LogMessage(Logger::STRING_CREATE_LOGIN_MANAGERS_METHOD); logger->LogMessage(Logger::STRING_CREATE_LOGIN_MANAGERS_METHOD);
} }
if (base::FeatureList::IsEnabled(
password_manager::features::kNewPasswordFormParsing)) {
CreateFormManagers(forms);
}
const PasswordForm::Scheme effective_form_scheme = const PasswordForm::Scheme effective_form_scheme =
forms.empty() ? PasswordForm::SCHEME_HTML : forms.front().scheme; forms.empty() ? PasswordForm::SCHEME_HTML : forms.front().scheme;
switch (effective_form_scheme) { switch (effective_form_scheme) {
...@@ -671,6 +679,27 @@ void PasswordManager::CreatePendingLoginManagers( ...@@ -671,6 +679,27 @@ void PasswordManager::CreatePendingLoginManagers(
} }
} }
void PasswordManager::CreateFormManagers(
const std::vector<autofill::PasswordForm>& forms) {
// Find new forms.
std::vector<const autofill::FormData*> new_forms;
for (const autofill::PasswordForm& form : forms) {
bool form_manager_exists =
std::any_of(form_managers_.begin(), form_managers_.end(),
[&form](const auto& form_manager) {
return form_manager->DoesManage(form.form_data);
});
if (!form_manager_exists)
new_forms.push_back(&form.form_data);
}
// Create form manager for new forms.
for (const autofill::FormData* new_form : new_forms) {
form_managers_.push_back(
std::make_unique<NewPasswordFormManager>(*new_form));
}
}
bool PasswordManager::OtherPossibleUsernamesEnabled() const { bool PasswordManager::OtherPossibleUsernamesEnabled() const {
return false; return false;
} }
......
...@@ -37,6 +37,7 @@ class BrowserSavePasswordProgressLogger; ...@@ -37,6 +37,7 @@ class BrowserSavePasswordProgressLogger;
class PasswordManagerClient; class PasswordManagerClient;
class PasswordManagerDriver; class PasswordManagerDriver;
class PasswordFormManager; class PasswordFormManager;
class NewPasswordFormManager;
// Per-tab password manager. Handles creation and management of UI elements, // Per-tab password manager. Handles creation and management of UI elements,
// receiving password form data from the renderer and managing the password // receiving password form data from the renderer and managing the password
...@@ -204,6 +205,10 @@ class PasswordManager : public LoginModel { ...@@ -204,6 +205,10 @@ class PasswordManager : public LoginModel {
pending_login_managers() { pending_login_managers() {
return pending_login_managers_; return pending_login_managers_;
} }
const std::vector<std::unique_ptr<NewPasswordFormManager>>& form_managers() {
return form_managers_;
}
#endif #endif
NavigationEntryToCheck entry_to_check() const { return entry_to_check_; } NavigationEntryToCheck entry_to_check() const { return entry_to_check_; }
...@@ -246,12 +251,16 @@ class PasswordManager : public LoginModel { ...@@ -246,12 +251,16 @@ class PasswordManager : public LoginModel {
// appropriate. // appropriate.
void OnLoginSuccessful(); void OnLoginSuccessful();
// Checks for every from in |forms| whether |pending_login_managers_| already // Checks for every form in |forms| whether |pending_login_managers_| already
// contain a manager for that form. If not, adds a manager for each such form. // contain a manager for that form. If not, adds a manager for each such form.
void CreatePendingLoginManagers( void CreatePendingLoginManagers(
password_manager::PasswordManagerDriver* driver, password_manager::PasswordManagerDriver* driver,
const std::vector<autofill::PasswordForm>& forms); const std::vector<autofill::PasswordForm>& forms);
// Checks for every form in |forms| whether |form_managers_| already contain a
// manager for that form. If not, adds a manager for each such form.
void CreateFormManagers(const std::vector<autofill::PasswordForm>& forms);
// Returns the best match in |pending_login_managers_| for |form|. May return // Returns the best match in |pending_login_managers_| for |form|. May return
// nullptr if no match exists. // nullptr if no match exists.
PasswordFormManager* GetMatchingPendingManager( PasswordFormManager* GetMatchingPendingManager(
...@@ -281,6 +290,9 @@ class PasswordManager : public LoginModel { ...@@ -281,6 +290,9 @@ class PasswordManager : public LoginModel {
// time a user submits a login form and gets to the next page. // time a user submits a login form and gets to the next page.
std::unique_ptr<PasswordFormManager> provisional_save_manager_; std::unique_ptr<PasswordFormManager> provisional_save_manager_;
// Contains one NewPasswordFormManager per each form on the page.
std::vector<std::unique_ptr<NewPasswordFormManager>> form_managers_;
// The embedder-level client. Must outlive this class. // The embedder-level client. Must outlive this class.
PasswordManagerClient* const client_; PasswordManagerClient* const client_;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "components/password_manager/core/browser/form_fetcher_impl.h" #include "components/password_manager/core/browser/form_fetcher_impl.h"
#include "components/password_manager/core/browser/mock_password_store.h" #include "components/password_manager/core/browser/mock_password_store.h"
#include "components/password_manager/core/browser/new_password_form_manager.h"
#include "components/password_manager/core/browser/password_autofill_manager.h" #include "components/password_manager/core/browser/password_autofill_manager.h"
#include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_reuse_defines.h" #include "components/password_manager/core/browser/password_reuse_defines.h"
...@@ -2326,4 +2327,25 @@ TEST_F(PasswordManagerTest, CertErrorReported) { ...@@ -2326,4 +2327,25 @@ TEST_F(PasswordManagerTest, CertErrorReported) {
} }
} }
TEST_F(PasswordManagerTest, CreatingFormManagers) {
// Add the NewPasswordFormParsing feature.
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kNewPasswordFormParsing);
PasswordForm form(MakeSimpleForm());
std::vector<PasswordForm> observed;
observed.push_back(form);
EXPECT_CALL(*store_, GetLogins(_, _))
.WillRepeatedly(WithArg<1>(InvokeEmptyConsumerWithForms()));
manager()->OnPasswordFormsParsed(&driver_, observed);
// Check that the form manager is created.
EXPECT_EQ(1u, manager()->form_managers().size());
EXPECT_TRUE(manager()->form_managers()[0]->DoesManage(form.form_data));
// Check that receiving the same form the second time does not lead to
// creating new form manager.
manager()->OnPasswordFormsParsed(&driver_, observed);
EXPECT_EQ(1u, manager()->form_managers().size());
}
} // namespace password_manager } // namespace password_manager
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment