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