Commit 34f136a0 authored by Ioana Pandele's avatar Ioana Pandele Committed by Commit Bot

[ReEPwdSave] Update the PasswordStore when saving is re-enabled

Tapping on the toggle in the keyboard accessory will now update
the PasswordStore, either by removing the blacklisted entry for
the origin if the user re-enables saving, or by re-adding it if
the user disables it again.

At the moment, the save password infobar is still not shown after
saving is enabled via the toggle, because ChromePasswordManagerClient
queries the old cache (via PasswordFormManager) which doesn't have the
latest store data. This will be changed in the next CL.

Bug: 1044930
Change-Id: I0a5cbcc6085fac5070375093b499a3e2ebc7c4e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2135752
Commit-Queue: Ioana Pandele <ioanap@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759660}
parent 44605943
...@@ -529,6 +529,15 @@ void ChromePasswordManagerClient::UpdateCredentialCache( ...@@ -529,6 +529,15 @@ void ChromePasswordManagerClient::UpdateCredentialCache(
#endif #endif
} }
void ChromePasswordManagerClient::UpdateCacheWithBlacklistedForOrigin(
const url::Origin& origin,
bool is_blacklisted) {
#if defined(OS_ANDROID)
credential_cache_.UpdateBlacklistedForOrigin(
origin, CredentialCache::IsOriginBlacklisted(is_blacklisted));
#endif
}
void ChromePasswordManagerClient::PasswordWasAutofilled( void ChromePasswordManagerClient::PasswordWasAutofilled(
const std::vector<const PasswordForm*>& best_matches, const std::vector<const PasswordForm*>& best_matches,
const GURL& origin, const GURL& origin,
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "content/public/browser/web_contents_receiver_set.h" #include "content/public/browser/web_contents_receiver_set.h"
#include "content/public/browser/web_contents_user_data.h" #include "content/public/browser/web_contents_user_data.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "url/origin.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "components/password_manager/core/browser/credential_cache.h" #include "components/password_manager/core/browser/credential_cache.h"
...@@ -123,6 +124,8 @@ class ChromePasswordManagerClient ...@@ -123,6 +124,8 @@ class ChromePasswordManagerClient
const GURL& origin, const GURL& origin,
const std::vector<const autofill::PasswordForm*>& best_matches, const std::vector<const autofill::PasswordForm*>& best_matches,
bool is_blacklisted) override; bool is_blacklisted) override;
void UpdateCacheWithBlacklistedForOrigin(const url::Origin& origin,
bool is_blacklisted) override;
void PasswordWasAutofilled( void PasswordWasAutofilled(
const std::vector<const autofill::PasswordForm*>& best_matches, const std::vector<const autofill::PasswordForm*>& best_matches,
const GURL& origin, const GURL& origin,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/feature_list.h" #include "base/feature_list.h"
...@@ -16,6 +17,8 @@ ...@@ -16,6 +17,8 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/autofill/manual_filling_controller.h"
#include "chrome/browser/autofill/manual_filling_utils.h" #include "chrome/browser/autofill/manual_filling_utils.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/password_manager/password_accessory_controller.h"
#include "chrome/browser/password_manager/password_accessory_metrics_util.h" #include "chrome/browser/password_manager/password_accessory_metrics_util.h"
#include "chrome/browser/password_manager/password_generation_controller.h" #include "chrome/browser/password_manager/password_generation_controller.h"
#include "chrome/browser/password_manager/password_manager_launcher_android.h" #include "chrome/browser/password_manager/password_manager_launcher_android.h"
...@@ -31,7 +34,9 @@ ...@@ -31,7 +34,9 @@
#include "components/password_manager/content/browser/content_password_manager_driver.h" #include "components/password_manager/content/browser/content_password_manager_driver.h"
#include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
#include "components/password_manager/core/browser/credential_cache.h"
#include "components/password_manager/core/browser/origin_credential_store.h" #include "components/password_manager/core/browser/origin_credential_store.h"
#include "components/password_manager/core/browser/password_manager_client.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_manager_util.h" #include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_features.h"
...@@ -45,6 +50,7 @@ using autofill::FooterCommand; ...@@ -45,6 +50,7 @@ using autofill::FooterCommand;
using autofill::UserInfo; using autofill::UserInfo;
using autofill::mojom::FocusedFieldType; using autofill::mojom::FocusedFieldType;
using password_manager::CredentialCache; using password_manager::CredentialCache;
using password_manager::PasswordStore;
using password_manager::UiCredential; using password_manager::UiCredential;
using BlacklistedStatus = using BlacklistedStatus =
password_manager::OriginCredentialStore::BlacklistedStatus; password_manager::OriginCredentialStore::BlacklistedStatus;
...@@ -142,8 +148,10 @@ void PasswordAccessoryControllerImpl::CreateForWebContents( ...@@ -142,8 +148,10 @@ void PasswordAccessoryControllerImpl::CreateForWebContents(
if (!FromWebContents(web_contents)) { if (!FromWebContents(web_contents)) {
web_contents->SetUserData( web_contents->SetUserData(
UserDataKey(), base::WrapUnique(new PasswordAccessoryControllerImpl( UserDataKey(),
web_contents, credential_cache))); base::WrapUnique(new PasswordAccessoryControllerImpl(
web_contents, credential_cache, nullptr,
ChromePasswordManagerClient::FromWebContents(web_contents))));
} }
} }
...@@ -151,15 +159,17 @@ void PasswordAccessoryControllerImpl::CreateForWebContents( ...@@ -151,15 +159,17 @@ void PasswordAccessoryControllerImpl::CreateForWebContents(
void PasswordAccessoryControllerImpl::CreateForWebContentsForTesting( void PasswordAccessoryControllerImpl::CreateForWebContentsForTesting(
content::WebContents* web_contents, content::WebContents* web_contents,
password_manager::CredentialCache* credential_cache, password_manager::CredentialCache* credential_cache,
base::WeakPtr<ManualFillingController> mf_controller) { base::WeakPtr<ManualFillingController> mf_controller,
password_manager::PasswordManagerClient* password_client) {
DCHECK(web_contents) << "Need valid WebContents to attach controller to!"; DCHECK(web_contents) << "Need valid WebContents to attach controller to!";
DCHECK(!FromWebContents(web_contents)) << "Controller already attached!"; DCHECK(!FromWebContents(web_contents)) << "Controller already attached!";
DCHECK(mf_controller); DCHECK(mf_controller);
DCHECK(password_client);
web_contents->SetUserData( web_contents->SetUserData(
UserDataKey(), UserDataKey(), base::WrapUnique(new PasswordAccessoryControllerImpl(
base::WrapUnique(new PasswordAccessoryControllerImpl( web_contents, credential_cache,
web_contents, credential_cache, std::move(mf_controller)))); std::move(mf_controller), password_client)));
} }
// static // static
...@@ -214,8 +224,7 @@ void PasswordAccessoryControllerImpl::OnToggleChanged( ...@@ -214,8 +224,7 @@ void PasswordAccessoryControllerImpl::OnToggleChanged(
autofill::AccessoryAction toggled_action, autofill::AccessoryAction toggled_action,
bool enabled) { bool enabled) {
if (toggled_action == autofill::AccessoryAction::TOGGLE_SAVE_PASSWORDS) { if (toggled_action == autofill::AccessoryAction::TOGGLE_SAVE_PASSWORDS) {
// TODO(crbug.com/1044930): Update the cache and the password store ChangeCurrentOriginSavePasswordsStatus(enabled);
// according to the toggle value.
return; return;
} }
NOTREACHED() << "Unhandled selected action: " NOTREACHED() << "Unhandled selected action: "
...@@ -300,19 +309,41 @@ void PasswordAccessoryControllerImpl::OnGenerationRequested( ...@@ -300,19 +309,41 @@ void PasswordAccessoryControllerImpl::OnGenerationRequested(
pwd_generation_controller->OnGenerationRequested(type); pwd_generation_controller->OnGenerationRequested(type);
} }
PasswordAccessoryControllerImpl::PasswordAccessoryControllerImpl(
content::WebContents* web_contents,
password_manager::CredentialCache* credential_cache)
: web_contents_(web_contents), credential_cache_(credential_cache) {}
// Additional creation functions in unit tests only:
PasswordAccessoryControllerImpl::PasswordAccessoryControllerImpl( PasswordAccessoryControllerImpl::PasswordAccessoryControllerImpl(
content::WebContents* web_contents, content::WebContents* web_contents,
password_manager::CredentialCache* credential_cache, password_manager::CredentialCache* credential_cache,
base::WeakPtr<ManualFillingController> mf_controller) base::WeakPtr<ManualFillingController> mf_controller,
password_manager::PasswordManagerClient* password_client)
: web_contents_(web_contents), : web_contents_(web_contents),
credential_cache_(credential_cache), credential_cache_(credential_cache),
mf_controller_(std::move(mf_controller)) {} mf_controller_(std::move(mf_controller)),
password_client_(password_client) {}
void PasswordAccessoryControllerImpl::ChangeCurrentOriginSavePasswordsStatus(
bool saving_enabled) {
const url::Origin origin = GetFocusedFrameOrigin();
if (origin.opaque())
return;
const GURL origin_as_gurl = origin.GetURL();
password_manager::PasswordStore::FormDigest form_digest(
autofill::PasswordForm::Scheme::kHtml,
password_manager::GetSignonRealm(origin_as_gurl), origin_as_gurl);
password_manager::PasswordStore* store =
password_client_->GetProfilePasswordStore();
password_client_->UpdateCacheWithBlacklistedForOrigin(origin,
!saving_enabled);
if (saving_enabled) {
store->Unblacklist(form_digest, base::NullCallback());
return;
}
autofill::PasswordForm form =
password_manager_util::MakeNormalizedBlacklistedForm(
std::move(form_digest));
form.date_created = base::Time::Now();
store->AddLogin(form);
}
bool PasswordAccessoryControllerImpl::AppearsInSuggestions( bool PasswordAccessoryControllerImpl::AppearsInSuggestions(
const base::string16& suggestion, const base::string16& suggestion,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/autofill/core/common/mojom/autofill_types.mojom-forward.h" #include "components/autofill/core/common/mojom/autofill_types.mojom-forward.h"
#include "components/autofill/core/common/password_generation_util.h" #include "components/autofill/core/common/password_generation_util.h"
#include "components/password_manager/core/browser/credential_cache.h" #include "components/password_manager/core/browser/credential_cache.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "content/public/browser/web_contents_user_data.h" #include "content/public/browser/web_contents_user_data.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -60,11 +61,12 @@ class PasswordAccessoryControllerImpl ...@@ -60,11 +61,12 @@ class PasswordAccessoryControllerImpl
// Like |CreateForWebContents|, it creates the controller and attaches it to // Like |CreateForWebContents|, it creates the controller and attaches it to
// the given |web_contents|. Additionally, it allows inject a manual filling // the given |web_contents|. Additionally, it allows inject a manual filling
// controller. // controller and a |PasswordManagerClient|.
static void CreateForWebContentsForTesting( static void CreateForWebContentsForTesting(
content::WebContents* web_contents, content::WebContents* web_contents,
password_manager::CredentialCache* credential_cache, password_manager::CredentialCache* credential_cache,
base::WeakPtr<ManualFillingController> mf_controller); base::WeakPtr<ManualFillingController> mf_controller,
password_manager::PasswordManagerClient* password_client);
// True if the focus event was sent for the current focused frame or if it is // True if the focus event was sent for the current focused frame or if it is
// a blur event and no frame is focused. This check avoids reacting to // a blur event and no frame is focused. This check avoids reacting to
...@@ -79,16 +81,18 @@ class PasswordAccessoryControllerImpl ...@@ -79,16 +81,18 @@ class PasswordAccessoryControllerImpl
private: private:
friend class content::WebContentsUserData<PasswordAccessoryControllerImpl>; friend class content::WebContentsUserData<PasswordAccessoryControllerImpl>;
// Required for construction via |CreateForWebContents|: // This constructor can also be used by |CreateForWebContentsForTesting|
PasswordAccessoryControllerImpl( // to inject a fake |ManualFillingController| and a fake
content::WebContents* contents, // |PasswordManagerClient|.
password_manager::CredentialCache* credential_cache);
// Constructor that allows to inject a mock or fake view.
PasswordAccessoryControllerImpl( PasswordAccessoryControllerImpl(
content::WebContents* web_contents, content::WebContents* web_contents,
password_manager::CredentialCache* credential_cache, password_manager::CredentialCache* credential_cache,
base::WeakPtr<ManualFillingController> mf_controller); base::WeakPtr<ManualFillingController> mf_controller,
password_manager::PasswordManagerClient* password_client);
// Enables or disables saving for the focused origin. This involves removing
// or adding blacklisted entry in the |PasswordStore|.
void ChangeCurrentOriginSavePasswordsStatus(bool enabled);
// Returns true if |suggestion| matches a credential for |origin|. // Returns true if |suggestion| matches a credential for |origin|.
bool AppearsInSuggestions(const base::string16& suggestion, bool AppearsInSuggestions(const base::string16& suggestion,
...@@ -106,14 +110,18 @@ class PasswordAccessoryControllerImpl ...@@ -106,14 +110,18 @@ class PasswordAccessoryControllerImpl
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// The tab for which this class is scoped. // The tab for which this class is scoped.
content::WebContents* web_contents_; content::WebContents* web_contents_ = nullptr;
// Keeps track of credentials which are stored for all origins in this tab. // Keeps track of credentials which are stored for all origins in this tab.
password_manager::CredentialCache* credential_cache_; password_manager::CredentialCache* credential_cache_ = nullptr;
// The password accessory controller object to forward client requests to. // The password accessory controller object to forward client requests to.
base::WeakPtr<ManualFillingController> mf_controller_; base::WeakPtr<ManualFillingController> mf_controller_;
// The password manager client is used to update the save passwords status
// for the currently focused origin.
password_manager::PasswordManagerClient* password_client_ = nullptr;
WEB_CONTENTS_USER_DATA_KEY_DECL(); WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(PasswordAccessoryControllerImpl); DISALLOW_COPY_AND_ASSIGN(PasswordAccessoryControllerImpl);
......
...@@ -22,21 +22,25 @@ ...@@ -22,21 +22,25 @@
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "components/autofill/core/browser/ui/accessory_sheet_enums.h"
#include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/password_generation_util.h" #include "components/autofill/core/common/password_generation_util.h"
#include "components/autofill/core/common/signatures_util.h" #include "components/autofill/core/common/signatures_util.h"
#include "components/password_manager/core/browser/credential_cache.h" #include "components/password_manager/core/browser/credential_cache.h"
#include "components/password_manager/core/browser/mock_password_store.h"
#include "components/password_manager/core/browser/origin_credential_store.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/stub_password_manager_client.h"
#include "components/password_manager/core/browser/stub_password_manager_driver.h" #include "components/password_manager/core/browser/stub_password_manager_driver.h"
#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_features.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "content/public/test/web_contents_tester.h" #include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/codec/png_codec.h" #include "ui/gfx/codec/png_codec.h"
#include "url/origin.h"
namespace { namespace {
using autofill::AccessoryAction; using autofill::AccessoryAction;
...@@ -49,8 +53,11 @@ using autofill::mojom::FocusedFieldType; ...@@ -49,8 +53,11 @@ using autofill::mojom::FocusedFieldType;
using base::ASCIIToUTF16; using base::ASCIIToUTF16;
using password_manager::CreateEntry; using password_manager::CreateEntry;
using password_manager::CredentialCache; using password_manager::CredentialCache;
using password_manager::MockPasswordStore;
using password_manager::OriginCredentialStore;
using testing::_; using testing::_;
using testing::ByMove; using testing::ByMove;
using testing::Eq;
using testing::Mock; using testing::Mock;
using testing::NiceMock; using testing::NiceMock;
using testing::Return; using testing::Return;
...@@ -61,6 +68,7 @@ using IsPslMatch = autofill::UserInfo::IsPslMatch; ...@@ -61,6 +68,7 @@ using IsPslMatch = autofill::UserInfo::IsPslMatch;
constexpr char kExampleSite[] = "https://example.com"; constexpr char kExampleSite[] = "https://example.com";
constexpr char kExampleSiteMobile[] = "https://m.example.com"; constexpr char kExampleSiteMobile[] = "https://m.example.com";
constexpr char kExampleSignonRealm[] = "https://example.com/";
constexpr char kExampleDomain[] = "example.com"; constexpr char kExampleDomain[] = "example.com";
class MockPasswordGenerationController class MockPasswordGenerationController
...@@ -70,8 +78,9 @@ class MockPasswordGenerationController ...@@ -70,8 +78,9 @@ class MockPasswordGenerationController
explicit MockPasswordGenerationController(content::WebContents* web_contents); explicit MockPasswordGenerationController(content::WebContents* web_contents);
MOCK_METHOD1(OnGenerationRequested, MOCK_METHOD(void,
void(autofill::password_generation::PasswordGenerationType)); OnGenerationRequested,
(autofill::password_generation::PasswordGenerationType));
}; };
// static // static
...@@ -87,6 +96,24 @@ MockPasswordGenerationController::MockPasswordGenerationController( ...@@ -87,6 +96,24 @@ MockPasswordGenerationController::MockPasswordGenerationController(
content::WebContents* web_contents) content::WebContents* web_contents)
: PasswordGenerationControllerImpl(web_contents) {} : PasswordGenerationControllerImpl(web_contents) {}
class MockPasswordManagerClient
: public password_manager::StubPasswordManagerClient {
public:
explicit MockPasswordManagerClient(MockPasswordStore* mock_password_store)
: mock_password_store_(mock_password_store) {}
MOCK_METHOD(void,
UpdateCacheWithBlacklistedForOrigin,
(const url::Origin&, bool));
password_manager::PasswordStore* GetProfilePasswordStore() const override {
return mock_password_store_;
}
private:
MockPasswordStore* mock_password_store_;
};
base::string16 password_for_str(const base::string16& user) { base::string16 password_for_str(const base::string16& user) {
return l10n_util::GetStringFUTF16( return l10n_util::GetStringFUTF16(
IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_DESCRIPTION, user); IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_DESCRIPTION, user);
...@@ -134,7 +161,9 @@ AccessorySheetData::Builder PasswordAccessorySheetDataBuilder( ...@@ -134,7 +161,9 @@ AccessorySheetData::Builder PasswordAccessorySheetDataBuilder(
class PasswordAccessoryControllerTest : public ChromeRenderViewHostTestHarness { class PasswordAccessoryControllerTest : public ChromeRenderViewHostTestHarness {
public: public:
PasswordAccessoryControllerTest() = default; PasswordAccessoryControllerTest()
: ChromeRenderViewHostTestHarness(
base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
void SetUp() override { void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp(); ChromeRenderViewHostTestHarness::SetUp();
...@@ -146,22 +175,36 @@ class PasswordAccessoryControllerTest : public ChromeRenderViewHostTestHarness { ...@@ -146,22 +175,36 @@ class PasswordAccessoryControllerTest : public ChromeRenderViewHostTestHarness {
web_contents()->GetFocusedFrame()->GetLastCommittedOrigin()); web_contents()->GetFocusedFrame()->GetLastCommittedOrigin());
MockPasswordGenerationController::CreateForWebContents(web_contents()); MockPasswordGenerationController::CreateForWebContents(web_contents());
mock_password_store_ = base::MakeRefCounted<MockPasswordStore>();
mock_password_store_->Init(nullptr);
mock_pwd_manager_client_ =
std::make_unique<MockPasswordManagerClient>(mock_password_store_.get());
PasswordAccessoryControllerImpl::CreateForWebContentsForTesting( PasswordAccessoryControllerImpl::CreateForWebContentsForTesting(
web_contents(), cache(), mock_manual_filling_controller_.AsWeakPtr()); web_contents(), cache(), mock_manual_filling_controller_.AsWeakPtr(),
mock_pwd_manager_client_.get());
NavigateAndCommit(GURL(kExampleSite)); NavigateAndCommit(GURL(kExampleSite));
} }
void TearDown() override { mock_password_store_->ShutdownOnUIThread(); }
PasswordAccessoryController* controller() { PasswordAccessoryController* controller() {
return PasswordAccessoryControllerImpl::FromWebContents(web_contents()); return PasswordAccessoryControllerImpl::FromWebContents(web_contents());
} }
password_manager::CredentialCache* cache() { return &credential_cache_; } password_manager::CredentialCache* cache() { return &credential_cache_; }
MockPasswordManagerClient* password_client() {
return mock_pwd_manager_client_.get();
}
protected: protected:
StrictMock<MockManualFillingController> mock_manual_filling_controller_; StrictMock<MockManualFillingController> mock_manual_filling_controller_;
scoped_refptr<MockPasswordStore> mock_password_store_;
private: private:
password_manager::CredentialCache credential_cache_; password_manager::CredentialCache credential_cache_;
std::unique_ptr<MockPasswordManagerClient> mock_pwd_manager_client_;
}; };
TEST_F(PasswordAccessoryControllerTest, IsNotRecreatedForSameWebContents) { TEST_F(PasswordAccessoryControllerTest, IsNotRecreatedForSameWebContents) {
...@@ -593,7 +636,8 @@ TEST_F(PasswordAccessoryControllerTest, ...@@ -593,7 +636,8 @@ TEST_F(PasswordAccessoryControllerTest,
FocusWebContentsOnMainFrame(); FocusWebContentsOnMainFrame();
PasswordAccessoryControllerImpl::CreateForWebContentsForTesting( PasswordAccessoryControllerImpl::CreateForWebContentsForTesting(
raw_web_contents, cache(), mock_manual_filling_controller_.AsWeakPtr()); raw_web_contents, cache(), mock_manual_filling_controller_.AsWeakPtr(),
password_client());
PasswordAccessoryController* incognito_accessory = PasswordAccessoryController* incognito_accessory =
PasswordAccessoryControllerImpl::FromWebContents(raw_web_contents); PasswordAccessoryControllerImpl::FromWebContents(raw_web_contents);
cache()->SaveCredentialsAndBlacklistedForOrigin( cache()->SaveCredentialsAndBlacklistedForOrigin(
...@@ -638,3 +682,32 @@ TEST_F(PasswordAccessoryControllerTest, AddsSaveToggleIfWasBlacklisted) { ...@@ -638,3 +682,32 @@ TEST_F(PasswordAccessoryControllerTest, AddsSaveToggleIfWasBlacklisted) {
FocusedFieldType::kFillablePasswordField, FocusedFieldType::kFillablePasswordField,
/*is_manual_generation_available=*/false); /*is_manual_generation_available=*/false);
} }
TEST_F(PasswordAccessoryControllerTest, SavePasswordsToggledUpdatesCache) {
url::Origin example_origin = url::Origin::Create(GURL(kExampleSite));
EXPECT_CALL(*password_client(),
UpdateCacheWithBlacklistedForOrigin(example_origin, false));
controller()->OnToggleChanged(
autofill::AccessoryAction::TOGGLE_SAVE_PASSWORDS, true);
}
TEST_F(PasswordAccessoryControllerTest, SavePasswordsEnabledUpdatesStore) {
password_manager::PasswordStore::FormDigest form_digest(
autofill::PasswordForm::Scheme::kHtml, kExampleSignonRealm,
GURL(kExampleSite));
EXPECT_CALL(*mock_password_store_, Unblacklist(form_digest, _));
controller()->OnToggleChanged(
autofill::AccessoryAction::TOGGLE_SAVE_PASSWORDS, true);
}
TEST_F(PasswordAccessoryControllerTest, SavePasswordsDisabledUpdatesStore) {
autofill::PasswordForm expected_form;
expected_form.blacklisted_by_user = true;
expected_form.scheme = autofill::PasswordForm::Scheme::kHtml;
expected_form.signon_realm = kExampleSignonRealm;
expected_form.origin = GURL(kExampleSite);
expected_form.date_created = base::Time::Now();
EXPECT_CALL(*mock_password_store_, AddLogin(Eq(expected_form)));
controller()->OnToggleChanged(
autofill::AccessoryAction::TOGGLE_SAVE_PASSWORDS, false);
}
...@@ -23,6 +23,8 @@ class MockPasswordStore : public PasswordStore { ...@@ -23,6 +23,8 @@ class MockPasswordStore : public PasswordStore {
MockPasswordStore(); MockPasswordStore();
MOCK_METHOD1(RemoveLogin, void(const autofill::PasswordForm&)); MOCK_METHOD1(RemoveLogin, void(const autofill::PasswordForm&));
MOCK_METHOD2(Unblacklist,
void(const PasswordStore::FormDigest&, base::OnceClosure));
MOCK_METHOD2(GetLogins, MOCK_METHOD2(GetLogins,
void(const PasswordStore::FormDigest&, PasswordStoreConsumer*)); void(const PasswordStore::FormDigest&, PasswordStoreConsumer*));
MOCK_METHOD2(GetLoginsByPassword, MOCK_METHOD2(GetLoginsByPassword,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "components/password_manager/core/browser/password_form_manager_for_ui.h"
#include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_client.h"
#include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/base/signin_metrics.h"
#include "url/origin.h"
namespace password_manager { namespace password_manager {
...@@ -46,6 +47,10 @@ void PasswordManagerClient::UpdateCredentialCache( ...@@ -46,6 +47,10 @@ void PasswordManagerClient::UpdateCredentialCache(
const std::vector<const autofill::PasswordForm*>& best_matches, const std::vector<const autofill::PasswordForm*>& best_matches,
bool is_blacklisted) {} bool is_blacklisted) {}
void PasswordManagerClient::UpdateCacheWithBlacklistedForOrigin(
const url::Origin& origin,
bool is_blacklisted) {}
void PasswordManagerClient::PasswordWasAutofilled( void PasswordManagerClient::PasswordWasAutofilled(
const std::vector<const autofill::PasswordForm*>& best_matches, const std::vector<const autofill::PasswordForm*>& best_matches,
const GURL& origin, const GURL& origin,
......
...@@ -214,6 +214,12 @@ class PasswordManagerClient { ...@@ -214,6 +214,12 @@ class PasswordManagerClient {
const std::vector<const autofill::PasswordForm*>& best_matches, const std::vector<const autofill::PasswordForm*>& best_matches,
bool is_blacklisted); bool is_blacklisted);
// Update the CredentialCache with information on whether the origin is
// blacklisted for passwords saving. This change is user-iniated from UI
// provided for this purpose. Currently only implemented on Android.
virtual void UpdateCacheWithBlacklistedForOrigin(const url::Origin& origin,
bool is_blacklisted);
// Called when a password is saved in an automated fashion. Embedder may // Called when a password is saved in an automated fashion. Embedder may
// inform the user that this save has occurred. // inform the user that this save has occurred.
virtual void AutomaticPasswordSave( virtual void AutomaticPasswordSave(
......
...@@ -213,8 +213,8 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -213,8 +213,8 @@ class PasswordStore : protected PasswordStoreSync,
// blacklisted entries. If |completion| is not null, it will be posted to the // blacklisted entries. If |completion| is not null, it will be posted to the
// |main_task_runner_| after deletions have been completed. Should be called // |main_task_runner_| after deletions have been completed. Should be called
// on the UI thread. // on the UI thread.
void Unblacklist(const PasswordStore::FormDigest& form_digest, virtual void Unblacklist(const PasswordStore::FormDigest& form_digest,
base::OnceClosure completion); base::OnceClosure completion);
// Searches for a matching PasswordForm, and notifies |consumer| on // Searches for a matching PasswordForm, and notifies |consumer| on
// completion. The request will be cancelled if the consumer is destroyed. // completion. The request will be cancelled if the consumer is destroyed.
......
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