about_signin_internals.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright (c) 2012 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#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ABOUT_SIGNIN_INTERNALS_H_
6#define COMPONENTS_SIGNIN_CORE_BROWSER_ABOUT_SIGNIN_INTERNALS_H_
7
8#include <map>
9#include <string>
10
11#include "base/memory/linked_ptr.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/observer_list.h"
14#include "base/values.h"
15#include "components/keyed_service/core/keyed_service.h"
16#include "components/signin/core/browser/signin_client.h"
17#include "components/signin/core/browser/signin_internals_util.h"
18#include "components/signin/core/browser/signin_manager.h"
19#include "google_apis/gaia/gaia_auth_consumer.h"
20#include "google_apis/gaia/oauth2_token_service.h"
21
22class GaiaAuthFetcher;
23class ProfileOAuth2TokenService;
24class SigninClient;
25class SigninManagerBase;
26
27// Many values in SigninStatus are also associated with a timestamp.
28// This makes it easier to keep values and their associated times together.
29typedef std::pair<std::string, std::string> TimedSigninStatusValue;
30
31// This class collects authentication, signin and token information
32// to propagate to about:signin-internals via SigninInternalsUI.
33class AboutSigninInternals
34    : public KeyedService,
35      public signin_internals_util::SigninDiagnosticsObserver,
36      public OAuth2TokenService::DiagnosticsObserver,
37      public GaiaAuthConsumer {
38 public:
39  class Observer {
40   public:
41    // |info| will contain the dictionary of signin_status_ values as indicated
42    // in the comments for GetSigninStatus() below.
43    virtual void OnSigninStateChanged(const base::DictionaryValue* info) = 0;
44
45    // Notification that the cookie accounts are ready to be displayed.
46    virtual void OnCookieAccountsFetched(const base::DictionaryValue* info) = 0;
47  };
48
49  AboutSigninInternals(ProfileOAuth2TokenService* token_service,
50                       SigninManagerBase* signin_manager);
51  virtual ~AboutSigninInternals();
52
53  // Each instance of SigninInternalsUI adds itself as an observer to be
54  // notified of all updates that AboutSigninInternals receives.
55  void AddSigninObserver(Observer* observer);
56  void RemoveSigninObserver(Observer* observer);
57
58  // Pulls all signin values that have been persisted in the user prefs.
59  void RefreshSigninPrefs();
60
61  // SigninManager::SigninDiagnosticsObserver implementation.
62  virtual void NotifySigninValueChanged(
63      const signin_internals_util::UntimedSigninStatusField& field,
64      const std::string& value) OVERRIDE;
65
66  virtual void NotifySigninValueChanged(
67      const signin_internals_util::TimedSigninStatusField& field,
68      const std::string& value) OVERRIDE;
69
70  void Initialize(SigninClient* client);
71
72  // KeyedService implementation.
73  virtual void Shutdown() OVERRIDE;
74
75  // Returns a dictionary of values in signin_status_ for use in
76  // about:signin-internals. The values are formatted as shown -
77  //
78  // { "signin_info" :
79  //     [ {"title": "Basic Information",
80  //        "data": [List of {"label" : "foo-field", "value" : "foo"} elems]
81  //       },
82  //       { "title": "Detailed Information",
83  //        "data": [List of {"label" : "foo-field", "value" : "foo"} elems]
84  //       }],
85  //   "token_info" :
86  //     [ List of {"name": "foo-name", "token" : "foo-token",
87  //                 "status": "foo_stat", "time" : "foo_time"} elems]
88  //  }
89  scoped_ptr<base::DictionaryValue> GetSigninStatus();
90
91  // Triggers a ListAccounts call to acquire a list of the email addresses
92  // corresponding to the cookies residing on the current cookie jar.
93  void GetCookieAccountsAsync();
94
95  // OAuth2TokenService::DiagnosticsObserver implementations.
96  virtual void OnAccessTokenRequested(
97      const std::string& account_id,
98      const std::string& consumer_id,
99      const OAuth2TokenService::ScopeSet& scopes) OVERRIDE;
100  virtual void OnFetchAccessTokenComplete(
101      const std::string& account_id,
102      const std::string& consumer_id,
103      const OAuth2TokenService::ScopeSet& scopes,
104      GoogleServiceAuthError error,
105      base::Time expiration_time) OVERRIDE;
106  virtual void OnTokenRemoved(const std::string& account_id,
107                              const OAuth2TokenService::ScopeSet& scopes)
108      OVERRIDE;
109
110    void OnRefreshTokenReceived(std::string status);
111    void OnAuthenticationResultReceived(std::string status);
112
113 private:
114  // Encapsulates diagnostic information about tokens for different services.
115  struct TokenInfo {
116    TokenInfo(const std::string& consumer_id,
117              const OAuth2TokenService::ScopeSet& scopes);
118    ~TokenInfo();
119    base::DictionaryValue* ToValue() const;
120
121    static bool LessThan(const TokenInfo* a, const TokenInfo* b);
122
123    // Called when the token is invalidated.
124    void Invalidate();
125
126    std::string consumer_id;              // service that requested the token.
127    OAuth2TokenService::ScopeSet scopes;  // Scoped that are requested.
128    base::Time request_time;
129    base::Time receive_time;
130    base::Time expiration_time;
131    GoogleServiceAuthError error;
132    bool removed_;
133  };
134
135  // Map account id to tokens associated to the account.
136  typedef std::map<std::string, std::vector<TokenInfo*> > TokenInfoMap;
137
138  // Encapsulates both authentication and token related information. Used
139  // by SigninInternals to maintain information that needs to be shown in
140  // the about:signin-internals page.
141  struct SigninStatus {
142    std::vector<std::string> untimed_signin_fields;
143    std::vector<TimedSigninStatusValue> timed_signin_fields;
144    TokenInfoMap token_info_map;
145
146    SigninStatus();
147    ~SigninStatus();
148
149    TokenInfo* FindToken(const std::string& account_id,
150                         const std::string& consumer_id,
151                         const OAuth2TokenService::ScopeSet& scopes);
152
153    // Returns a dictionary with the following form:
154    // { "signin_info" :
155    //     [ {"title": "Basic Information",
156    //        "data": [List of {"label" : "foo-field", "value" : "foo"} elems]
157    //       },
158    //       { "title": "Detailed Information",
159    //        "data": [List of {"label" : "foo-field", "value" : "foo"} elems]
160    //       }],
161    //   "token_info" :
162    //     [ List of
163    //       { "title": account id,
164    //         "data": [List of {"service" : service name,
165    //                           "scopes" : requested scoped,
166    //                           "request_time" : request time,
167    //                           "status" : request status} elems]
168    //       }],
169    //  }
170    scoped_ptr<base::DictionaryValue> ToValue(std::string product_version);
171  };
172
173  void NotifyObservers();
174
175
176  // Overriden from GaiaAuthConsumer.
177  virtual void OnListAccountsSuccess(const std::string& data) OVERRIDE;
178  virtual void OnListAccountsFailure(const GoogleServiceAuthError& error)
179      OVERRIDE;
180
181  // Callback for ListAccounts. Once the email addresses are fetched from GAIA,
182  // they are pushed to the signin_internals_ui.
183  void OnListAccountsComplete(
184      std::vector<std::pair<std::string, bool> >& gaia_accounts);
185
186  // Called when a cookie changes. If the cookie relates to a GAIA LSID cookie,
187  // then we call ListAccounts and update the UI element.
188  void OnCookieChanged(const net::CanonicalCookie* cookie);
189
190  // Weak pointer to the token service.
191  ProfileOAuth2TokenService* token_service_;
192
193  // Weak pointer to the signin manager.
194  SigninManagerBase* signin_manager_;
195
196  // Weak pointer to the client.
197  SigninClient* client_;
198
199  // Fetcher for information about accounts in the cookie jar from GAIA.
200  scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
201
202  // Encapsulates the actual signin and token related values.
203  // Most of the values are mirrored in the prefs for persistence.
204  SigninStatus signin_status_;
205
206  ObserverList<Observer> signin_observers_;
207
208  scoped_ptr<SigninClient::CookieChangedCallbackList::Subscription>
209      cookie_changed_subscription_;
210
211  DISALLOW_COPY_AND_ASSIGN(AboutSigninInternals);
212};
213
214#endif  // COMPONENTS_SIGNIN_CORE_BROWSER_ABOUT_SIGNIN_INTERNALS_H_
215