1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The signin manager encapsulates some functionality tracking
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// which user is signed in.
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// **NOTE** on semantics of SigninManager:
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Once a signin is successful, the username becomes "established" and will not
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// be cleared until a SignOut operation is performed (persists across
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// restarts). Until that happens, the signin manager can still be used to
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// refresh credentials, but changing the username is not permitted.
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// On Chrome OS, because of the existence of other components that handle login
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// and signin at a higher level, all that is needed from a SigninManager is
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// caching / handling of the "authenticated username" field, and TokenService
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// initialization, so that components that depend on these two things
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// (i.e on desktop) can continue using it / don't need to change. For this
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// reason, SigninManagerBase is all that exists on Chrome OS. For desktop,
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// see signin/signin_manager.h.
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_BASE_H_
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_BASE_H_
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/compiler_specific.h"
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/gtest_prod_util.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/observer_list.h"
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/prefs/pref_member.h"
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h"
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/signin_internals_util.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PrefService;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass SigninClient;
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class SigninManagerBase : public KeyedService {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  class Observer {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   public:
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Called when a user fails to sign into Google services such as sync.
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    virtual void GoogleSigninFailed(const GoogleServiceAuthError& error) {}
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Called when a user signs into Google services such as sync.
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    virtual void GoogleSigninSucceeded(const std::string& account_id,
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       const std::string& username,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       const std::string& password) {}
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Called when the currently signed-in user for a user has been signed out.
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    virtual void GoogleSignedOut(const std::string& account_id,
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 const std::string& username) {}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   protected:
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    virtual ~Observer() {}
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SigninManagerBase(SigninClient* client);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~SigninManagerBase();
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If user was signed in, load tokens from DB if available.
67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void Initialize(PrefService* local_state);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsInitialized() const;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true if a signin to Chrome is allowed (by policy or pref).
71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // TODO(tim): kSigninAllowed is defined for all platforms in pref_names.h.
72a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // If kSigninAllowed pref was non-Chrome OS-only, this method wouldn't be
73a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // needed, but as is we provide this method to let all interested code
74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // code query the value in one way, versus half using PrefService directly
75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // and the other half using SigninManager.
76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual bool IsSigninAllowed() const;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If a user has previously signed in (and has not signed out), this returns
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the normalized email address of the account. Otherwise, it returns an empty
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // string.
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string& GetAuthenticatedUsername() const;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If a user has previously signed in (and has not signed out), this returns
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the account id. Otherwise, it returns an empty string.  This id can be used
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to uniquely identify an account, so for example can be used as a key to
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // map accounts to data.
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(rogerta): eventually the account id should be an obfuscated gaia id.
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For now though, this function returns the same value as
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GetAuthenticatedUsername() since lots of code assumes the unique id for an
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // account is the username.  For code that needs a unique id to represent the
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // connected account, call this method. Example: the AccountInfoMap type
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in MutableProfileOAuth2TokenService.  For code that needs to know the
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // normalized email address of the connected account, use
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GetAuthenticatedUsername().  Example: to show the string "Signed in as XXX"
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in the hotdog menu.
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::string& GetAuthenticatedAccountId() const;
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sets the user name.  Note: |username| should be already authenticated as
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // this is a sticky operation (in contrast to StartSignIn).
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(tim): Remove this in favor of passing username on construction by
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // (by platform / depending on StartBehavior). Bug 88109.
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetAuthenticatedUsername(const std::string& username);
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns true if there is an authenticated user.
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool IsAuthenticated() const;
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true if there's a signin in progress.
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool AuthInProgress() const;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // KeyedService implementation.
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Shutdown() OVERRIDE;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Methods to register or remove observers of signin.
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AddObserver(Observer* observer);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void RemoveObserver(Observer* observer);
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Methods to register or remove SigninDiagnosticObservers.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void AddSigninDiagnosticsObserver(
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      signin_internals_util::SigninDiagnosticsObserver* observer);
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RemoveSigninDiagnosticsObserver(
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      signin_internals_util::SigninDiagnosticsObserver* observer);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Used by subclass to clear authenticated_username_ instead of using
126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // SetAuthenticatedUsername, which enforces special preconditions due
127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // to the fact that it is part of the public API and called by clients.
128a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  void clear_authenticated_username();
129a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // List of observers to notify on signin events.
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Makes sure list is empty on destruction.
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ObserverList<Observer, true> observer_list_;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Helper methods to notify all registered diagnostics observers with.
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void NotifyDiagnosticsObservers(
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const signin_internals_util::UntimedSigninStatusField& field,
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& value);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void NotifyDiagnosticsObservers(
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const signin_internals_util::TimedSigninStatusField& field,
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& value);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class FakeSigninManagerBase;
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class FakeSigninManager;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SigninClient* client_;
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool initialized_;
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Actual username after successful authentication.
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string authenticated_username_;
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The list of SigninDiagnosticObservers.
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ObserverList<signin_internals_util::SigninDiagnosticsObserver, true>
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      signin_diagnostics_observers_;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WeakPtrFactory<SigninManagerBase> weak_pointer_factory_;
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SigninManagerBase);
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif  // COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_BASE_H_
162