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 // The PrimaryAccountManager encapsulates some functionality tracking 6 // which account is the primary one. 7 // 8 // **NOTE** on semantics of PrimaryAccountManager: 9 // 10 // Once a signin is successful, the username becomes "established" and will not 11 // be cleared until a SignOut operation is performed (persists across 12 // restarts). Until that happens, the primary account manager can still be used 13 // to refresh credentials, but changing the username is not permitted. 14 // 15 // On ChromeOS signout is not possible, so that functionality is if-def'd out on 16 // that platform. 17 18 #ifndef COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MANAGER_H_ 19 #define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MANAGER_H_ 20 21 #include <memory> 22 #include <string> 23 24 #include "base/macros.h" 25 #include "base/observer_list.h" 26 #include "base/observer_list_types.h" 27 #include "base/optional.h" 28 #include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h" 29 #include "components/signin/public/base/account_consistency_method.h" 30 #include "components/signin/public/base/signin_client.h" 31 #include "components/signin/public/identity_manager/account_info.h" 32 33 class AccountTrackerService; 34 class PrefRegistrySimple; 35 class PrefService; 36 class PrimaryAccountPolicyManager; 37 class ProfileOAuth2TokenService; 38 39 namespace signin_metrics { 40 enum ProfileSignout : int; 41 enum class SignoutDelete; 42 } // namespace signin_metrics 43 44 class PrimaryAccountManager : public ProfileOAuth2TokenServiceObserver { 45 public: 46 class Observer : public base::CheckedObserver { 47 public: 48 // Called whenever a user signs into Google services such as sync. 49 // Not called during a reauth. GoogleSigninSucceeded(const CoreAccountInfo & info)50 virtual void GoogleSigninSucceeded(const CoreAccountInfo& info) {} 51 52 // Called whenever the unconsented primary account changes. This includes 53 // the changes for the consented primary account as well. UnconsentedPrimaryAccountChanged(const CoreAccountInfo & info)54 virtual void UnconsentedPrimaryAccountChanged(const CoreAccountInfo& info) { 55 } 56 57 // Called whenever the currently signed-in user has been signed out. GoogleSignedOut(const CoreAccountInfo & info)58 virtual void GoogleSignedOut(const CoreAccountInfo& info) {} 59 }; 60 61 // Used to remove accounts from the token service and the account tracker. 62 enum class RemoveAccountsOption { 63 // Do not remove accounts. 64 kKeepAllAccounts = 0, 65 #if !defined(OS_CHROMEOS) 66 // Remove all the accounts. 67 kRemoveAllAccounts, 68 // Removes the authenticated account if it is in authentication error. 69 kRemoveAuthenticatedAccountIfInError 70 #endif 71 }; 72 73 PrimaryAccountManager( 74 SigninClient* client, 75 ProfileOAuth2TokenService* token_service, 76 AccountTrackerService* account_tracker_service, 77 signin::AccountConsistencyMethod account_consistency, 78 std::unique_ptr<PrimaryAccountPolicyManager> policy_manager); 79 ~PrimaryAccountManager() override; 80 81 // Registers per-profile prefs. 82 static void RegisterProfilePrefs(PrefRegistrySimple* registry); 83 84 // Registers per-install prefs. 85 static void RegisterPrefs(PrefRegistrySimple* registry); 86 87 // If user was signed in, load tokens from DB if available. 88 void Initialize(PrefService* local_state); 89 bool IsInitialized() const; 90 91 // If a user has previously signed in (and has not signed out), this returns 92 // the know information of the account. Otherwise, it returns an empty struct. 93 CoreAccountInfo GetAuthenticatedAccountInfo() const; 94 95 // If a user has previously signed in (and has not signed out), this returns 96 // the account id. Otherwise, it returns an empty CoreAccountId. This id is 97 // the G+/Focus obfuscated gaia id of the user. It can be used to uniquely 98 // identify an account, so for example as a key to map accounts to data. For 99 // code that needs a unique id to represent the connected account, call this 100 // method. Example: the AccountStatusMap type in 101 // MutableProfileOAuth2TokenService. For code that needs to know the 102 // normalized email address of the connected account, use 103 // GetAuthenticatedAccountInfo().email. Example: to show the string 104 // "Signed in as XXX" in the hotdog menu. 105 CoreAccountId GetAuthenticatedAccountId() const; 106 107 // Returns true if there is an authenticated user. 108 bool IsAuthenticated() const; 109 110 // Signs a user in. PrimaryAccountManager assumes that |username| can be used 111 // to look up the corresponding account_id and gaia_id for this email. 112 void SignIn(const std::string& username); 113 114 // Updates the authenticated account information from AccountTrackerService. 115 void UpdateAuthenticatedAccountInfo(); 116 117 // Signout API surfaces (not supported on ChromeOS, where signout is not 118 // permitted). 119 #if !defined(OS_CHROMEOS) 120 // Signs a user out, removing the preference, erasing all keys 121 // associated with the authenticated user, and canceling all auth in progress. 122 // On mobile and on desktop pre-DICE, this also removes all accounts from 123 // Chrome by revoking all refresh tokens. 124 // On desktop with DICE enabled, this will remove the authenticated account 125 // from Chrome only if it is in authentication error. No other accounts are 126 // removed. 127 void SignOut(signin_metrics::ProfileSignout signout_source_metric, 128 signin_metrics::SignoutDelete signout_delete_metric); 129 130 // Signs a user out, removing the preference, erasing all keys 131 // associated with the authenticated user, and canceling all auth in progress. 132 // It removes all accounts from Chrome by revoking all refresh tokens. 133 void SignOutAndRemoveAllAccounts( 134 signin_metrics::ProfileSignout signout_source_metric, 135 signin_metrics::SignoutDelete signout_delete_metric); 136 137 // Signs a user out, removing the preference, erasing all keys 138 // associated with the authenticated user, and canceling all auth in progress. 139 // Does not remove the accounts from the token service. 140 void SignOutAndKeepAllAccounts( 141 signin_metrics::ProfileSignout signout_source_metric, 142 signin_metrics::SignoutDelete signout_delete_metric); 143 #endif // !defined(OS_CHROMEOS) 144 145 #if defined(OS_CHROMEOS) 146 // Revokes sync consent from the primary account. The primary account must 147 // have sync consent. After the call a primary account will remain but it will 148 // not have sync consent. 149 void RevokeSyncConsent(); 150 #endif // defined(OS_CHROMEOS) 151 152 // Adds and removes observers. 153 void AddObserver(Observer* observer); 154 void RemoveObserver(Observer* observer); 155 156 // Provides access to the core information of the user's unconsented primary 157 // account. Returns an empty info, if there is no such account. 158 CoreAccountInfo GetUnconsentedPrimaryAccountInfo() const; 159 160 // Returns whether the user's unconsented primary account is available. 161 bool HasUnconsentedPrimaryAccount() const; 162 163 // Sets the unconsented primary account. The unconsented primary account can 164 // only be changed if the user is not authenticated. If the user is 165 // authenticated, use Signout() instead. 166 void SetUnconsentedPrimaryAccountInfo(CoreAccountInfo account_info); 167 168 private: 169 // Sets the authenticated user's account id, when the user has consented to 170 // sync. 171 // If the user is already authenticated with the same account id, then this 172 // method is a no-op. 173 // It is forbidden to call this method if the user is already authenticated 174 // with a different account (this method will DCHECK in that case). 175 // |account_id| must not be empty. To log the user out, use 176 // ClearAuthenticatedAccountId() instead. 177 void SetAuthenticatedAccountInfo(const CoreAccountInfo& account_info); 178 179 // Sets |primary_account_info_| and updates the associated preferences. 180 void SetPrimaryAccountInternal(const CoreAccountInfo& account_info, 181 bool consented_to_sync); 182 183 // Starts the sign out process. If |assert_signout_allowed| is true then 184 // the sign out process will DCHECK if user sign out is not allowed. 185 void StartSignOut(signin_metrics::ProfileSignout signout_source_metric, 186 signin_metrics::SignoutDelete signout_delete_metric, 187 RemoveAccountsOption remove_option, 188 bool assert_signout_allowed = false); 189 190 // The sign out process which is started by SigninClient::PreSignOut() 191 void OnSignoutDecisionReached( 192 signin_metrics::ProfileSignout signout_source_metric, 193 signin_metrics::SignoutDelete signout_delete_metric, 194 RemoveAccountsOption remove_option, 195 bool assert_signout_allowed, 196 SigninClient::SignoutDecision signout_decision); 197 198 #if !defined(OS_CHROMEOS) 199 // ProfileOAuth2TokenServiceObserver: 200 void OnRefreshTokensLoaded() override; 201 #endif 202 primary_account_info()203 const CoreAccountInfo& primary_account_info() const { 204 return primary_account_info_; 205 } 206 207 SigninClient* client_; 208 209 // The ProfileOAuth2TokenService instance associated with this object. Must 210 // outlive this object. 211 ProfileOAuth2TokenService* token_service_ = nullptr; 212 AccountTrackerService* account_tracker_service_ = nullptr; 213 214 bool initialized_ = false; 215 216 // Account id after successful authentication. The account may or may not be 217 // consented to Sync. 218 // Must be kept in sync with prefs. Use SetPrimaryAccountInternal() to change 219 // this field. 220 CoreAccountInfo primary_account_info_; 221 222 #if !defined(OS_CHROMEOS) 223 signin::AccountConsistencyMethod account_consistency_; 224 #endif 225 226 std::unique_ptr<PrimaryAccountPolicyManager> policy_manager_; 227 base::ObserverList<Observer> observers_; 228 229 DISALLOW_COPY_AND_ASSIGN(PrimaryAccountManager); 230 }; 231 232 #endif // COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MANAGER_H_ 233