1 // Copyright 2014 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/signin/core/browser/signin_manager_base.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/command_line.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/prefs/pref_service.h" 13 #include "base/strings/string_split.h" 14 #include "base/strings/string_util.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "components/signin/core/browser/signin_client.h" 17 #include "components/signin/core/common/signin_pref_names.h" 18 #include "components/signin/core/common/signin_switches.h" 19 #include "google_apis/gaia/gaia_auth_util.h" 20 #include "google_apis/gaia/gaia_constants.h" 21 #include "google_apis/gaia/gaia_urls.h" 22 23 using namespace signin_internals_util; 24 25 SigninManagerBase::SigninManagerBase(SigninClient* client) 26 : client_(client), initialized_(false), weak_pointer_factory_(this) {} 27 28 SigninManagerBase::~SigninManagerBase() {} 29 30 void SigninManagerBase::Initialize(PrefService* local_state) { 31 // Should never call Initialize() twice. 32 DCHECK(!IsInitialized()); 33 initialized_ = true; 34 35 // If the user is clearing the token service from the command line, then 36 // clear their login info also (not valid to be logged in without any 37 // tokens). 38 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 39 if (cmd_line->HasSwitch(switches::kClearTokenService)) 40 client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername); 41 42 std::string user = 43 client_->GetPrefs()->GetString(prefs::kGoogleServicesUsername); 44 if (!user.empty()) { 45 #if defined(OS_IOS) 46 // Prior to M38, Chrome on iOS did not normalize the email before setting 47 // it in SigninManager. |AccountReconcilor| expects the authenticated email 48 // to be normalized as it used as an account identifier and is compared 49 // to the accounts available in the cookies. 50 user = gaia::CanonicalizeEmail(gaia::SanitizeEmail(user)); 51 #endif 52 SetAuthenticatedUsername(user); 53 } 54 } 55 56 bool SigninManagerBase::IsInitialized() const { return initialized_; } 57 58 bool SigninManagerBase::IsSigninAllowed() const { 59 return client_->GetPrefs()->GetBoolean(prefs::kSigninAllowed); 60 } 61 62 const std::string& SigninManagerBase::GetAuthenticatedUsername() const { 63 return authenticated_username_; 64 } 65 66 const std::string& SigninManagerBase::GetAuthenticatedAccountId() const { 67 return GetAuthenticatedUsername(); 68 } 69 70 void SigninManagerBase::SetAuthenticatedUsername(const std::string& username) { 71 if (!authenticated_username_.empty()) { 72 DLOG_IF(ERROR, !gaia::AreEmailsSame(username, authenticated_username_)) 73 << "Tried to change the authenticated username to something different: " 74 << "Current: " << authenticated_username_ << ", New: " << username; 75 76 #if defined(OS_IOS) 77 // Prior to M26, chrome on iOS did not normalize the email before setting 78 // it in SigninManager. If the emails are the same as given by 79 // gaia::AreEmailsSame() but not the same as given by std::string::op==(), 80 // make sure to set the authenticated name below. 81 if (!gaia::AreEmailsSame(username, authenticated_username_) || 82 username == authenticated_username_) { 83 return; 84 } 85 #else 86 return; 87 #endif 88 } 89 std::string pref_username = 90 client_->GetPrefs()->GetString(prefs::kGoogleServicesUsername); 91 DCHECK(pref_username.empty() || gaia::AreEmailsSame(username, pref_username)) 92 << "username: " << username << "; pref_username: " << pref_username; 93 authenticated_username_ = username; 94 client_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username); 95 NotifyDiagnosticsObservers(USERNAME, username); 96 97 // Go ahead and update the last signed in username here as well. Once a 98 // user is signed in the two preferences should match. Doing it here as 99 // opposed to on signin allows us to catch the upgrade scenario. 100 client_->GetPrefs()->SetString(prefs::kGoogleServicesLastUsername, username); 101 } 102 103 void SigninManagerBase::clear_authenticated_username() { 104 authenticated_username_.clear(); 105 } 106 107 bool SigninManagerBase::IsAuthenticated() const { 108 return !GetAuthenticatedAccountId().empty(); 109 } 110 111 bool SigninManagerBase::AuthInProgress() const { 112 // SigninManagerBase never kicks off auth processes itself. 113 return false; 114 } 115 116 void SigninManagerBase::Shutdown() {} 117 118 void SigninManagerBase::AddObserver(Observer* observer) { 119 observer_list_.AddObserver(observer); 120 } 121 122 void SigninManagerBase::RemoveObserver(Observer* observer) { 123 observer_list_.RemoveObserver(observer); 124 } 125 126 void SigninManagerBase::AddSigninDiagnosticsObserver( 127 SigninDiagnosticsObserver* observer) { 128 signin_diagnostics_observers_.AddObserver(observer); 129 } 130 131 void SigninManagerBase::RemoveSigninDiagnosticsObserver( 132 SigninDiagnosticsObserver* observer) { 133 signin_diagnostics_observers_.RemoveObserver(observer); 134 } 135 136 void SigninManagerBase::NotifyDiagnosticsObservers( 137 const UntimedSigninStatusField& field, 138 const std::string& value) { 139 FOR_EACH_OBSERVER(SigninDiagnosticsObserver, 140 signin_diagnostics_observers_, 141 NotifySigninValueChanged(field, value)); 142 } 143 144 void SigninManagerBase::NotifyDiagnosticsObservers( 145 const TimedSigninStatusField& field, 146 const std::string& value) { 147 FOR_EACH_OBSERVER(SigninDiagnosticsObserver, 148 signin_diagnostics_observers_, 149 NotifySigninValueChanged(field, value)); 150 } 151