1// Copyright 2013 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 CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_H_ 6#define CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_H_ 7 8#include <string> 9 10#include "base/gtest_prod_util.h" 11#include "chrome/browser/signin/oauth2_token_service.h" 12#include "chrome/browser/signin/signin_global_error.h" 13#include "components/browser_context_keyed_service/browser_context_keyed_service.h" 14#include "components/webdata/common/web_data_service_consumer.h" 15#include "content/public/browser/notification_observer.h" 16#include "content/public/browser/notification_registrar.h" 17 18namespace net { 19class URLRequestContextGetter; 20} 21 22class GoogleServiceAuthError; 23class Profile; 24class TokenService; 25class SigninGlobalError; 26 27// ProfileOAuth2TokenService is a BrowserContextKeyedService that retrieves 28// OAuth2 access tokens for a given set of scopes using the OAuth2 login 29// refresh token maintained by TokenService. 30// 31// See |OAuth2TokenService| for usage details. 32// 33// Note: after StartRequest returns, in-flight requests will continue 34// even if the TokenService refresh token that was used to initiate 35// the request changes or is cleared. When the request completes, 36// Consumer::OnGetTokenSuccess will be invoked, but the access token 37// won't be cached. 38// 39// Note: requests should be started from the UI thread. To start a 40// request from other thread, please use ProfileOAuth2TokenServiceRequest. 41class ProfileOAuth2TokenService : public OAuth2TokenService, 42 public content::NotificationObserver, 43 public SigninGlobalError::AuthStatusProvider, 44 public BrowserContextKeyedService, 45 public WebDataServiceConsumer { 46 public: 47 // content::NotificationObserver listening for TokenService updates. 48 virtual void Observe(int type, 49 const content::NotificationSource& source, 50 const content::NotificationDetails& details) OVERRIDE; 51 52 // Initializes this token service with the profile. 53 virtual void Initialize(Profile* profile); 54 55 // BrowserContextKeyedService implementation. 56 virtual void Shutdown() OVERRIDE; 57 58 // SigninGlobalError::AuthStatusProvider implementation. 59 virtual GoogleServiceAuthError GetAuthStatus() const OVERRIDE; 60 61 // OAuth2TokenService implementation. 62 virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE; 63 64 // Takes injected TokenService for testing. 65 bool ShouldCacheForRefreshToken(TokenService *token_service, 66 const std::string& refresh_token); 67 68 // Updates a |refresh_token| for an |account_id|. Credentials are persisted, 69 // and avialable through |LoadCredentials| after service is restarted. 70 void UpdateCredentials(const std::string& account_id, 71 const std::string& refresh_token); 72 73 // Revokes credentials related to |account_id|. 74 void RevokeCredentials(const std::string& account_id); 75 76 // Revokes all credentials handled by the object. 77 void RevokeAllCredentials(); 78 79 SigninGlobalError* signin_global_error() { 80 return signin_global_error_.get(); 81 } 82 83 const SigninGlobalError* signin_global_error() const { 84 return signin_global_error_.get(); 85 } 86 87 Profile* profile() const { return profile_; } 88 89 protected: 90 friend class ProfileOAuth2TokenServiceFactory; 91 ProfileOAuth2TokenService(); 92 virtual ~ProfileOAuth2TokenService(); 93 94 // OAuth2TokenService overrides. 95 virtual std::string GetRefreshToken() OVERRIDE; 96 97 // Updates the internal cache of the result from the most-recently-completed 98 // auth request (used for reporting errors to the user). 99 virtual void UpdateAuthError(const GoogleServiceAuthError& error) OVERRIDE; 100 101 // Overridden to not cache tokens if the TokenService refresh token 102 // changes while a token fetch is in-flight. If the user logs out and 103 // logs back in with a different account, then any in-flight token 104 // fetches will be for the old account's refresh token. Therefore 105 // when they come back, they shouldn't be cached. 106 virtual void RegisterCacheEntry(const std::string& refresh_token, 107 const ScopeSet& scopes, 108 const std::string& access_token, 109 const base::Time& expiration_date) OVERRIDE; 110 111 private: 112 FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest, 113 StaleRefreshTokensNotCached); 114 FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest, 115 TokenServiceUpdateClearsCache); 116 FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest, 117 PersistenceDBUpgrade); 118 FRIEND_TEST_ALL_PREFIXES(ProfileOAuth2TokenServiceTest, 119 PersistenceLoadCredentials); 120 121 // WebDataServiceConsumer implementation: 122 virtual void OnWebDataServiceRequestDone( 123 WebDataServiceBase::Handle handle, 124 const WDTypedResult* result) OVERRIDE; 125 126 // Loads credentials from a backing persistent store to make them available 127 // after service is used between profile restarts. 128 void LoadCredentials(); 129 130 // Loads credentials into in memory stucture. 131 void LoadAllCredentialsIntoMemory( 132 const std::map<std::string, std::string>& db_tokens); 133 134 // Loads a single pair of |account_id|, |refresh_token| into memory. 135 void LoadCredentialsIntoMemory(const std::string& account_id, 136 const std::string& refresh_token); 137 138 // The profile with which this instance was initialized, or NULL. 139 Profile* profile_; 140 141 // Handle to the request reading tokens from database. 142 WebDataServiceBase::Handle web_data_service_request_; 143 144 // In memory refresh token store mapping account_id to refresh_token. 145 std::map<std::string, std::string> refresh_tokens_; 146 147 // Used to show auth errors in the wrench menu. The SigninGlobalError is 148 // different than most GlobalErrors in that its lifetime is controlled by 149 // ProfileOAuth2TokenService (so we can expose a reference for use in the 150 // wrench menu). 151 scoped_ptr<SigninGlobalError> signin_global_error_; 152 153 // The auth status from the most-recently-completed request. 154 GoogleServiceAuthError last_auth_error_; 155 156 // Registrar for notifications from the TokenService. 157 content::NotificationRegistrar registrar_; 158 159 DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenService); 160}; 161 162#endif // CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_H_ 163