Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Unified Diff: components/password_manager/core/browser/login_database_unittest.cc

Issue 2899083004: Implement PasswordStore::GetLoginsForSameOrganizationName. (Closed)
Patch Set: Rebase. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/password_manager/core/browser/login_database_unittest.cc
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index b15468f57bbbb4768c7fd2e107d07dfe461721b5..3d86b18fd3dd723d166969c09a0aad887025e954 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -21,6 +21,7 @@
#include "build/build_config.h"
#include "components/autofill/core/common/password_form.h"
#include "components/os_crypt/os_crypt_mocker.h"
+#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/psl_matching_helper.h"
#include "sql/connection.h"
#include "sql/statement.h"
@@ -789,6 +790,146 @@ TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingRegexp) {
EXPECT_EQ(0U, result.size());
}
+TEST_F(LoginDatabaseTest,
+ GetLoginsForSameOrganizationName_OnlyWebHTTPFormsAreConsidered) {
+ const struct {
+ const PasswordFormData form_data;
+ const char* other_queried_signon_realm;
+ bool expected_matches_itself;
+ bool expected_matches_other_realm;
+ } kTestCases[] = {
+ {{PasswordForm::SCHEME_HTML, "https://example.com/",
+ "https://example.com/origin", "", L"", L"", L"", L"u", L"p", false, 1},
+ nullptr,
+ true,
+ true},
+ {{PasswordForm::SCHEME_BASIC, "http://example.com/realm",
+ "http://example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
+ nullptr,
+ false,
+ false},
+ {{PasswordForm::SCHEME_OTHER, "ftp://example.com/realm",
+ "ftp://example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
+ "http://example.com/realm",
+ false,
+ false},
+ {{PasswordForm::SCHEME_HTML,
+ "federation://example.com/accounts.google.com",
+ "https://example.com/orgin", "", L"", L"", L"", L"u",
+ kTestingFederatedLoginMarker, false, 1},
+ "http://example.com/",
+ false,
+ false},
+ {{PasswordForm::SCHEME_HTML, "android://hash@example.com/",
+ "android://hash@example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
+ "http://example.com/",
+ false,
+ false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.form_data.signon_realm);
+
+ std::unique_ptr<PasswordForm> form =
+ CreatePasswordFormFromDataForTesting(test_case.form_data);
+ ASSERT_EQ(AddChangeForForm(*form), db().AddLogin(*form));
+
+ std::vector<std::unique_ptr<PasswordForm>> same_organization_forms;
+ EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
+ form->signon_realm, &same_organization_forms));
+ EXPECT_EQ(test_case.expected_matches_itself ? 1u : 0u,
+ same_organization_forms.size());
+
+ if (test_case.other_queried_signon_realm) {
+ same_organization_forms.clear();
+ EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
+ test_case.other_queried_signon_realm, &same_organization_forms));
+ EXPECT_EQ(test_case.expected_matches_other_realm ? 1u : 0u,
+ same_organization_forms.size());
+ }
+
+ ASSERT_TRUE(db().RemoveLogin(*form));
+ }
+}
+
+TEST_F(LoginDatabaseTest, GetLoginsForSameOrganizationName_DetailsOfMatching) {
+ const struct {
+ const char* saved_signon_realm;
+ const char* queried_signon_realm;
+ bool expected_matches;
+ } kTestCases[] = {
+ // PSL matches are also same-organization-name matches.
+ {"http://psl.example.com/", "http://example.com/", true},
+ {"http://example.com/", "http://sub.example.com/", true},
+ {"https://a.b.example.co.uk/", "https://c.d.e.example.co.uk/", true},
+
+ // Non-PSL but same-organization-name matches. Also an illustration why it
+ // would be unsafe to offer these credentials for filling.
+ {"https://example.com/", "https://example.co.uk/", true},
+ {"https://example.co.uk/", "https://example.com/", true},
+ {"https://a.example.appspot.com/", "https://b.example.co.uk/", true},
+
+ // Same-organization-name matches are HTTP/HTTPS-agnostic.
+ {"https://example.com/", "http://example.com/", true},
+ {"http://example.com/", "https://example.com/", true},
+
+ {"http://www.foo-bar.com/", "http://sub.foo-bar.com", true},
+ {"http://www.foo_bar.com/", "http://sub.foo_bar.com", true},
+ {"http://www.foo-bar.com/", "http://sub.foo%2Dbar.com", true},
+ {"http://www.foo%21bar.com/", "http://sub.foo!bar.com", true},
+ {"http://a.xn--sztr-7na0i.co.uk/", "http://xn--sztr-7na0i.com/", true},
+ {"http://a.xn--sztr-7na0i.co.uk/", "http://www.sz\xc3\xb3t\xc3\xa1r.com/",
+ true},
+
+ {"http://www.foo+bar.com/", "http://sub.foo+bar.com", true},
+ {"http://www.foooobar.com/", "http://sub.foo+bar.com", false},
+ {"http://www.fobar.com/", "http://sub.foo?bar.com", false},
+ {"http://www.foozbar.com/", "http://sub.foo.bar.com", false},
+ {"http://www.foozbar.com/", "http://sub.foo[a-z]bar.com", false},
+
+ {"https://notexample.com/", "https://example.com/", false},
+ {"https://a.notexample.com/", "https://example.com/", false},
+ {"https://example.com/", "https://notexample.com/", false},
+ {"https://example.com/", "https://example.bar.com/", false},
+ {"https://example.foo.com/", "https://example.com/", false},
+ {"https://example.foo.com/", "https://example.bar.com/", false},
+
+ // URLs without host portions, hosts without registry controlled domains
+ // or hosts consisting of a registry.
+ {"http://localhost/", "http://localhost/", false},
+ {"https://example/", "https://example/", false},
+ {"https://co.uk/", "https://co.uk/", false},
+ {"https://example/", "https://example.com/", false},
+ {"https://a.example/", "https://example.com/", false},
+ {"https://example.com/", "https://example/", false},
+ {"https://127.0.0.1/", "https://127.0.0.1/", false},
+ {"https:/[3ffe:2a00:100:7031::1]/", "https:/[3ffe:2a00:100:7031::1]/",
+ false},
+
+ // Queried |signon-realms| are invalid URIs.
+ {"https://example.com/", "", false},
+ {"https://example.com/", "bad url", false},
+ {"https://example.com/", "https://", false},
+ {"https://example.com/", "http://www.foo;bar.com", false},
+ {"https://example.com/", "example", false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.saved_signon_realm);
+ SCOPED_TRACE(test_case.queried_signon_realm);
+
+ std::unique_ptr<PasswordForm> form = CreatePasswordFormFromDataForTesting(
+ {PasswordForm::SCHEME_HTML, test_case.saved_signon_realm,
+ test_case.saved_signon_realm, "", L"", L"", L"", L"u", L"p", true, 1});
+ std::vector<std::unique_ptr<PasswordForm>> result;
+ ASSERT_EQ(AddChangeForForm(*form), db().AddLogin(*form));
+ EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
+ test_case.queried_signon_realm, &result));
+ EXPECT_EQ(test_case.expected_matches ? 1u : 0u, result.size());
+ ASSERT_TRUE(db().RemoveLogin(*form));
+ }
+}
+
static bool AddTimestampedLogin(LoginDatabase* db,
std::string url,
const std::string& unique_string,

Powered by Google App Engine
This is Rietveld 408576698