| Index: components/password_manager/core/browser/password_manager_unittest.cc
|
| diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
|
| index f45f191dc78c45ac5e8a20f6a9ae5010fd4f3621..61e0ab0c1a780b3853043aa7ef13b4987414ec56 100644
|
| --- a/components/password_manager/core/browser/password_manager_unittest.cc
|
| +++ b/components/password_manager/core/browser/password_manager_unittest.cc
|
| @@ -33,6 +33,7 @@ using base::ASCIIToUTF16;
|
| using testing::_;
|
| using testing::AnyNumber;
|
| using testing::Return;
|
| +using testing::ReturnRef;
|
| using testing::SaveArg;
|
| using testing::WithArg;
|
|
|
| @@ -67,6 +68,7 @@ class MockPasswordManagerClient : public StubPasswordManagerClient {
|
| void(const autofill::PasswordForm&));
|
| MOCK_METHOD0(AutomaticPasswordSaveIndicator, void());
|
| MOCK_METHOD0(GetPrefs, PrefService*());
|
| + MOCK_CONST_METHOD0(GetMainFrameURL, const GURL&());
|
| MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
|
| MOCK_CONST_METHOD0(GetStoreResultFilter, const MockStoreResultFilter*());
|
|
|
| @@ -135,6 +137,9 @@ class PasswordManagerTest : public testing::Test {
|
| .WillRepeatedly(Return(password_autofill_manager_.get()));
|
| EXPECT_CALL(client_, DidLastPageLoadEncounterSSLErrors())
|
| .WillRepeatedly(Return(false));
|
| +
|
| + ON_CALL(client_, GetMainFrameURL())
|
| + .WillByDefault(ReturnRef(GURL::EmptyGURL()));
|
| }
|
|
|
| void TearDown() override {
|
| @@ -748,6 +753,104 @@ TEST_F(PasswordManagerTest,
|
| manager()->OnPasswordFormsRendered(&driver_, observed, true);
|
| }
|
|
|
| +TEST_F(PasswordManagerTest,
|
| + ShouldBlockPasswordForSameOriginButDifferentSchemeTest) {
|
| + PasswordForm form = MakeSimpleForm();
|
| +
|
| + // Same origin and same scheme.
|
| + manager()->main_frame_url_ = GURL("https://example.com/login");
|
| + form.origin = GURL("https://example.com/login");
|
| + EXPECT_FALSE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +
|
| + // Same host and same scheme, different port.
|
| + manager()->main_frame_url_ = GURL("https://example.com:443/login");
|
| + form.origin = GURL("https://example.com:444/login");
|
| + EXPECT_FALSE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +
|
| + // Same host but different scheme (https to http).
|
| + manager()->main_frame_url_ = GURL("https://example.com/login");
|
| + form.origin = GURL("http://example.com/login");
|
| + EXPECT_TRUE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +
|
| + // Same host but different scheme (http to https).
|
| + manager()->main_frame_url_ = GURL("https://example.com/login");
|
| + form.origin = GURL("http://example.com/login");
|
| + EXPECT_TRUE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +
|
| + // Different TLD, same schemes.
|
| + manager()->main_frame_url_ = GURL("https://example.com/login");
|
| + form.origin = GURL("https://example.org/login");
|
| + EXPECT_FALSE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +
|
| + // Different TLD, different schemes.
|
| + manager()->main_frame_url_ = GURL("https://example.com/login");
|
| + form.origin = GURL("http://example.org/login");
|
| + EXPECT_FALSE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +
|
| + // Different subdomains, same schemes.
|
| + manager()->main_frame_url_ = GURL("https://sub1.example.com/login");
|
| + form.origin = GURL("https://sub2.example.org/login");
|
| + EXPECT_FALSE(
|
| + manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
|
| +}
|
| +
|
| +// Tests whether two submissions to the same origin but different schemes
|
| +// result in only saving the first submission, which has a secure scheme.
|
| +TEST_F(PasswordManagerTest, AttemptedSavePasswordSameOriginInsecureScheme) {
|
| + PasswordForm secure_form(MakeSimpleForm());
|
| + secure_form.origin = GURL("https://example.com/login");
|
| + secure_form.action = GURL("https://example.com/login");
|
| + secure_form.signon_realm = secure_form.origin.spec();
|
| +
|
| + PasswordForm insecure_form(MakeSimpleForm());
|
| + insecure_form.username_value = ASCIIToUTF16("compromised_user");
|
| + insecure_form.password_value = ASCIIToUTF16("C0mpr0m1s3d_P4ss");
|
| + insecure_form.origin = GURL("http://example.com/home");
|
| + insecure_form.action = GURL("http://example.com/home");
|
| + insecure_form.signon_realm = insecure_form.origin.spec();
|
| +
|
| + EXPECT_CALL(*store_, GetLogins(_, _))
|
| + .WillRepeatedly(WithArg<1>(InvokeEmptyConsumerWithForms()));
|
| +
|
| + EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage())
|
| + .WillRepeatedly(Return(true));
|
| +
|
| + EXPECT_CALL(client_, GetMainFrameURL())
|
| + .WillRepeatedly(ReturnRef(secure_form.origin));
|
| +
|
| + // See and submit both forms.
|
| + std::vector<PasswordForm> observed = {secure_form};
|
| + manager()->OnPasswordFormsParsed(&driver_, observed);
|
| + manager()->OnPasswordFormsRendered(&driver_, observed, false);
|
| + OnPasswordFormSubmitted(secure_form);
|
| +
|
| + observed = {insecure_form};
|
| + manager()->OnPasswordFormsParsed(&driver_, observed);
|
| + manager()->OnPasswordFormsRendered(&driver_, observed, false);
|
| + OnPasswordFormSubmitted(insecure_form);
|
| +
|
| + std::unique_ptr<PasswordFormManager> form_manager_to_save;
|
| + EXPECT_CALL(client_,
|
| + PromptUserToSaveOrUpdatePasswordPtr(
|
| + _, CredentialSourceType::CREDENTIAL_SOURCE_PASSWORD_MANAGER))
|
| + .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save)));
|
| +
|
| + // Navigation after form submit, no forms appear.
|
| + observed.clear();
|
| + manager()->OnPasswordFormsParsed(&driver_, observed);
|
| + manager()->OnPasswordFormsRendered(&driver_, observed, true);
|
| +
|
| + EXPECT_CALL(*store_, AddLogin(FormMatches(secure_form)));
|
| + ASSERT_TRUE(form_manager_to_save);
|
| + form_manager_to_save->Save();
|
| +}
|
| +
|
| // Create a form with both a new and current password element. Let the current
|
| // password value be non-empty and the new password value be empty and submit
|
| // the form. While normally saving the new password is preferred (on change
|
|
|