summaryrefslogtreecommitdiffstats
path: root/chrome/browser/signin/profile_oauth2_token_service.h
blob: a920e5efb8077efd6e818a6173ecb944757e69d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_H_
#define CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_H_

#include <string>

#include "base/gtest_prod_util.h"
#include "chrome/browser/signin/oauth2_token_service.h"
#include "chrome/browser/signin/signin_global_error.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "components/webdata/common/web_data_service_consumer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"

namespace net {
class URLRequestContextGetter;
}

class GoogleServiceAuthError;
class Profile;
class TokenService;
class SigninGlobalError;

// ProfileOAuth2TokenService is a BrowserContextKeyedService that retrieves
// OAuth2 access tokens for a given set of scopes using the OAuth2 login
// refresh token maintained by TokenService.
//
// See |OAuth2TokenService| for usage details.
//
// Note: after StartRequest returns, in-flight requests will continue
// even if the TokenService refresh token that was used to initiate
// the request changes or is cleared.  When the request completes,
// Consumer::OnGetTokenSuccess will be invoked, but the access token
// won't be cached.
//
// Note: requests should be started from the UI thread. To start a
// request from other thread, please use ProfileOAuth2TokenServiceRequest.
class ProfileOAuth2TokenService : public OAuth2TokenService,
                                  public content::NotificationObserver,
                                  public SigninGlobalError::AuthStatusProvider,
                                  public BrowserContextKeyedService,
                                  public WebDataServiceConsumer {
 public:
  // content::NotificationObserver listening for TokenService updates.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  // Initializes this token service with the profile.
  virtual void Initialize(Profile* profile);

  // BrowserContextKeyedService implementation.
  virtual void Shutdown() OVERRIDE;

  // SigninGlobalError::AuthStatusProvider implementation.
  virtual GoogleServiceAuthError GetAuthStatus() const OVERRIDE;

  // Takes injected TokenService for testing.
  bool ShouldCacheForRefreshToken(TokenService *token_service,
                                  const std::string& refresh_token);

  // Updates a |refresh_token| for an |account_id|. Credentials are persisted,
  // and avialable through |LoadCredentials| after service is restarted.
  void UpdateCredentials(const std::string& account_id,
                         const std::string& refresh_token);

  // Revokes credentials related to |account_id|.
  void RevokeCredentials(const std::string& account_id);

  // Revokes all credentials handled by the object.
  void RevokeAllCredentials();

  SigninGlobalError* signin_global_error() {
    return signin_global_error_.get();
  }

  const SigninGlobalError* signin_global_error() const {
    return signin_global_error_.get();
  }

  Profile* profile() const { return profile_; }

 protected:
  friend class ProfileOAuth2TokenServiceFactory;
  ProfileOAuth2TokenService();
  virtual ~ProfileOAuth2TokenService();

  // OAuth2TokenService overrides.
  virtual std::string GetRefreshToken() OVERRIDE;

  // OAuth2TokenService implementation.
  virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;

  // Updates the internal cache of the result from the most-recently-completed
  // auth request (used for reporting errors to the user).
  virtual void UpdateAuthError(const GoogleServiceAuthError& error) OVERRIDE;

  // Overridden to not cache tokens if the TokenService refresh token
  // changes while a token fetch is in-flight.  If the user logs out and
  // logs back in with a different account, then any in-flight token
  // fetches will be for the old account's refresh token.  Therefore
  // when they come back, they shouldn't be cached.
  virtual void RegisterCacheEntry(const std::string& refresh_token,
                                  const ScopeSet& scopes,
                                  const std::string& access_token,
                                  const base::Time& expiration_date) OVERRIDE;

 private:
  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest,
                           StaleRefreshTokensNotCached);
  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest,
                           TokenServiceUpdateClearsCache);
  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest,
                           PersistenceDBUpgrade);
  FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest,
                           PersistenceLoadCredentials);

  // WebDataServiceConsumer implementation:
  virtual void OnWebDataServiceRequestDone(
      WebDataServiceBase::Handle handle,
      const WDTypedResult* result) OVERRIDE;

  // Loads credentials from a backing persistent store to make them available
  // after service is used between profile restarts.
  void LoadCredentials();

  // Loads credentials into in memory stucture.
  void LoadAllCredentialsIntoMemory(
      const std::map<std::string, std::string>& db_tokens);

  // Loads a single pair of |account_id|, |refresh_token| into memory.
  void LoadCredentialsIntoMemory(const std::string& account_id,
                                 const std::string& refresh_token);

  // The profile with which this instance was initialized, or NULL.
  Profile* profile_;

  // Handle to the request reading tokens from database.
  WebDataServiceBase::Handle web_data_service_request_;

  // In memory refresh token store mapping account_id to refresh_token.
  std::map<std::string, std::string> refresh_tokens_;

  // Used to show auth errors in the wrench menu. The SigninGlobalError is
  // different than most GlobalErrors in that its lifetime is controlled by
  // ProfileOAuth2TokenService (so we can expose a reference for use in the
  // wrench menu).
  scoped_ptr<SigninGlobalError> signin_global_error_;

  // The auth status from the most-recently-completed request.
  GoogleServiceAuthError last_auth_error_;

  // Registrar for notifications from the TokenService.
  content::NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenService);
};

#endif  // CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_H_