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