Index: components/password_manager/core/browser/login_database.cc |
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc |
index 5de021e0ea7f70dfed308a45bfe280a20d6961a4..686899d9dec51144f3afac5e63e5647070887edf 100644 |
--- a/components/password_manager/core/browser/login_database.cc |
+++ b/components/password_manager/core/browser/login_database.cc |
@@ -30,12 +30,14 @@ |
#include "components/password_manager/core/browser/password_manager_client.h" |
#include "components/password_manager/core/browser/password_manager_metrics_util.h" |
#include "components/password_manager/core/browser/password_manager_util.h" |
+#include "components/password_manager/core/browser/psl_matching_helper.h" |
#include "components/password_manager/core/browser/sql_table_builder.h" |
#include "google_apis/gaia/gaia_auth_util.h" |
#include "google_apis/gaia/gaia_urls.h" |
#include "sql/connection.h" |
#include "sql/statement.h" |
#include "sql/transaction.h" |
+#include "third_party/re2/src/re2/re2.h" |
#include "url/origin.h" |
#include "url/url_constants.h" |
@@ -1133,6 +1135,48 @@ bool LoginDatabase::GetLogins( |
return false; |
} |
+bool LoginDatabase::GetLoginsForSameOrganizationName( |
+ const std::string& signon_realm, |
+ std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const { |
+ DCHECK(forms); |
+ forms->clear(); |
+ |
+ GURL signon_realm_as_url(signon_realm); |
+ if (!signon_realm_as_url.SchemeIsHTTPOrHTTPS()) |
+ return true; |
+ |
+ std::string organization_name = |
+ GetOrganizationIdentifyingName(signon_realm_as_url); |
+ if (organization_name.empty()) |
+ return true; |
+ |
+ // SQLite does not provide a function to escape special characters, but |
+ // seemingly uses POSIX Extended Regular Expressions (ERE), and so does RE2. |
+ // In the worst case the bogus results will be filtered out below. |
+ static constexpr char kRESchemeOrSubdomains[] = "^https?://([\\w+%-]+\\.)*"; |
+ static constexpr char kREDotAndEffectiveTLD[] = "(\\.[\\w+%-]+)+/$"; |
+ const std::string signon_realms_with_same_organization_name_regexp = |
+ kRESchemeOrSubdomains + RE2::QuoteMeta(organization_name) + |
+ kREDotAndEffectiveTLD; |
+ sql::Statement s(db_.GetCachedStatement( |
+ SQL_FROM_HERE, get_same_organization_name_logins_statement_.c_str())); |
+ s.BindString(0, signon_realms_with_same_organization_name_regexp); |
+ |
+ bool success = StatementToForms(&s, nullptr, forms); |
+ |
+ using PasswordFormPtr = std::unique_ptr<autofill::PasswordForm>; |
+ base::EraseIf(*forms, [&organization_name](const PasswordFormPtr& form) { |
+ GURL candidate_signon_realm(form->signon_realm); |
+ DCHECK_EQ(form->scheme, PasswordForm::SCHEME_HTML); |
+ DCHECK(candidate_signon_realm.SchemeIsHTTPOrHTTPS()); |
+ std::string candidate_form_organization_name = |
+ GetOrganizationIdentifyingName(GURL(candidate_signon_realm)); |
vasilii
2017/05/26 10:53:36
candidate_signon_realm is already GURL.
engedy
2017/05/26 10:58:43
Done.
|
+ return candidate_form_organization_name != organization_name; |
+ }); |
+ |
+ return success; |
+} |
+ |
bool LoginDatabase::GetLoginsCreatedBetween( |
const base::Time begin, |
const base::Time end, |
@@ -1315,6 +1359,11 @@ void LoginDatabase::InitializeStatementStrings(const SQLTableBuilder& builder) { |
DCHECK(get_statement_psl_federated_.empty()); |
get_statement_psl_federated_ = |
get_statement_ + psl_statement + psl_federated_statement; |
+ DCHECK(get_same_organization_name_logins_statement_.empty()); |
+ get_same_organization_name_logins_statement_ = |
+ "SELECT " + all_column_names + |
+ " FROM LOGINS" |
+ " WHERE scheme == 0 AND signon_realm REGEXP ?"; |
DCHECK(created_statement_.empty()); |
created_statement_ = |
"SELECT " + all_column_names + |