1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/password_manager/core/browser/password_sync_util.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "build/build_config.h"
9 #include "components/autofill/core/common/password_form.h"
10 #include "components/signin/public/identity_manager/identity_manager.h"
11 #include "components/sync/base/user_selectable_type.h"
12 #include "components/sync/driver/sync_user_settings.h"
13 #include "google_apis/gaia/gaia_auth_util.h"
14 #include "google_apis/gaia/gaia_urls.h"
15 #include "url/origin.h"
16
17 #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
18 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
19 #endif // SYNC_PASSWORD_REUSE_DETECTION_ENABLED
20
21 using autofill::PasswordForm;
22 using url::Origin;
23
24 namespace {
25
26 constexpr char kGoogleChangePasswordSignonRealm[] =
27 "https://myaccount.google.com/";
28
29 } // namespace
30
31 namespace password_manager {
32 namespace sync_util {
33
GetSyncUsernameIfSyncingPasswords(const syncer::SyncService * sync_service,const signin::IdentityManager * identity_manager)34 std::string GetSyncUsernameIfSyncingPasswords(
35 const syncer::SyncService* sync_service,
36 const signin::IdentityManager* identity_manager) {
37 if (!identity_manager)
38 return std::string();
39
40 // Return early if the user has explicitly disabled password sync. Note that
41 // this does not cover the case when sync as a whole is turned off.
42 if (sync_service && !sync_service->GetUserSettings()->GetSelectedTypes().Has(
43 syncer::UserSelectableType::kPasswords)) {
44 return std::string();
45 }
46
47 return identity_manager->GetPrimaryAccountInfo().email;
48 }
49
IsSyncAccountCredential(const autofill::PasswordForm & form,const syncer::SyncService * sync_service,const signin::IdentityManager * identity_manager)50 bool IsSyncAccountCredential(const autofill::PasswordForm& form,
51 const syncer::SyncService* sync_service,
52 const signin::IdentityManager* identity_manager) {
53 if (!GURL(form.signon_realm).DomainIs("google.com"))
54 return false;
55
56 // The empty username can mean that Chrome did not detect it correctly. For
57 // reasons described in http://crbug.com/636292#c1, the username is suspected
58 // to be the sync username unless proven otherwise.
59 if (form.username_value.empty())
60 return true;
61
62 return gaia::AreEmailsSame(
63 base::UTF16ToUTF8(form.username_value),
64 GetSyncUsernameIfSyncingPasswords(sync_service, identity_manager));
65 }
66
IsSyncAccountEmail(const std::string & username,const signin::IdentityManager * identity_manager)67 bool IsSyncAccountEmail(const std::string& username,
68 const signin::IdentityManager* identity_manager) {
69 // |identity_manager| can be null if user is not signed in.
70 if (!identity_manager)
71 return false;
72
73 std::string sync_email = identity_manager->GetPrimaryAccountInfo().email;
74
75 if (sync_email.empty() || username.empty())
76 return false;
77
78 if (username.find('@') == std::string::npos)
79 return false;
80
81 return gaia::AreEmailsSame(username, sync_email);
82 }
83
IsGaiaCredentialPage(const std::string & signon_realm)84 bool IsGaiaCredentialPage(const std::string& signon_realm) {
85 return gaia::IsGaiaSignonRealm(GURL(signon_realm)) ||
86 signon_realm == kGoogleChangePasswordSignonRealm;
87 }
88
ShouldSaveEnterprisePasswordHash(const autofill::PasswordForm & form,const PrefService & prefs)89 bool ShouldSaveEnterprisePasswordHash(const autofill::PasswordForm& form,
90 const PrefService& prefs) {
91 #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
92 return safe_browsing::MatchesPasswordProtectionLoginURL(form.origin, prefs) ||
93 safe_browsing::MatchesPasswordProtectionChangePasswordURL(form.origin,
94 prefs);
95 #else
96 return false;
97 #endif // SYNC_PASSWORD_REUSE_DETECTION_ENABLED
98 }
99
100 } // namespace sync_util
101 } // namespace password_manager
102