| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "google_apis/gaia/oauth2_token_service.h" | 5 #include "google_apis/gaia/oauth2_token_service.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "base/timer/timer.h" | 15 #include "base/timer/timer.h" |
| 16 #include "google_apis/gaia/gaia_urls.h" | 16 #include "google_apis/gaia/gaia_urls.h" |
| 17 #include "google_apis/gaia/google_service_auth_error.h" | 17 #include "google_apis/gaia/google_service_auth_error.h" |
| 18 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
| 19 | 19 |
| 20 int OAuth2TokenService::max_fetch_retry_num_ = 5; | 20 int OAuth2TokenService::max_fetch_retry_num_ = 5; |
| 21 | 21 |
| 22 OAuth2TokenService::ClientScopeSet::ClientScopeSet( | 22 OAuth2TokenService::RequestParameters::RequestParameters( |
| 23 const std::string& client_id, | 23 const std::string& client_id, |
| 24 const std::string& account_id, |
| 24 const ScopeSet& scopes) | 25 const ScopeSet& scopes) |
| 25 : client_id(client_id), | 26 : client_id(client_id), |
| 27 account_id(account_id), |
| 26 scopes(scopes) { | 28 scopes(scopes) { |
| 27 } | 29 } |
| 28 | 30 |
| 29 OAuth2TokenService::ClientScopeSet::~ClientScopeSet() { | 31 OAuth2TokenService::RequestParameters::~RequestParameters() { |
| 30 } | 32 } |
| 31 | 33 |
| 32 bool OAuth2TokenService::ClientScopeSet::operator<( | 34 bool OAuth2TokenService::RequestParameters::operator<( |
| 33 const ClientScopeSet& s) const { | 35 const RequestParameters& p) const { |
| 34 if (client_id < s.client_id) | |
| 35 return true; | |
| 36 else if (s.client_id < client_id) | |
| 37 return false; | |
| 38 | |
| 39 return scopes < s.scopes; | |
| 40 } | |
| 41 | |
| 42 OAuth2TokenService::FetchParameters::FetchParameters( | |
| 43 const std::string& client_id, | |
| 44 const std::string& refresh_token, | |
| 45 const ScopeSet& scopes) | |
| 46 : client_id(client_id), | |
| 47 refresh_token(refresh_token), | |
| 48 scopes(scopes) { | |
| 49 } | |
| 50 | |
| 51 OAuth2TokenService::FetchParameters::~FetchParameters() { | |
| 52 } | |
| 53 | |
| 54 bool OAuth2TokenService::FetchParameters::operator<( | |
| 55 const FetchParameters& p) const { | |
| 56 if (client_id < p.client_id) | 36 if (client_id < p.client_id) |
| 57 return true; | 37 return true; |
| 58 else if (p.client_id < client_id) | 38 else if (p.client_id < client_id) |
| 59 return false; | 39 return false; |
| 60 | 40 |
| 61 if (refresh_token < p.refresh_token) | 41 if (account_id < p.account_id) |
| 62 return true; | 42 return true; |
| 63 else if (p.refresh_token < refresh_token) | 43 else if (p.account_id < account_id) |
| 64 return false; | 44 return false; |
| 65 | 45 |
| 66 return scopes < p.scopes; | 46 return scopes < p.scopes; |
| 67 } | 47 } |
| 68 | 48 |
| 69 OAuth2TokenService::RequestImpl::RequestImpl( | 49 OAuth2TokenService::RequestImpl::RequestImpl( |
| 70 OAuth2TokenService::Consumer* consumer) | 50 OAuth2TokenService::Consumer* consumer) |
| 71 : consumer_(consumer) { | 51 : consumer_(consumer) { |
| 72 } | 52 } |
| 73 | 53 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 // before it completes fetching, or | 95 // before it completes fetching, or |
| 116 // - when the Fetcher is destructed if the Fetcher is destructed before it | 96 // - when the Fetcher is destructed if the Fetcher is destructed before it |
| 117 // completes fetching (in this case, the waiting requests will be called | 97 // completes fetching (in this case, the waiting requests will be called |
| 118 // back with error). | 98 // back with error). |
| 119 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { | 99 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
| 120 public: | 100 public: |
| 121 // Creates a Fetcher and starts fetching an OAuth2 access token for | 101 // Creates a Fetcher and starts fetching an OAuth2 access token for |
| 122 // |refresh_token| and |scopes| in the request context obtained by |getter|. | 102 // |refresh_token| and |scopes| in the request context obtained by |getter|. |
| 123 // The given |oauth2_token_service| will be informed when fetching is done. | 103 // The given |oauth2_token_service| will be informed when fetching is done. |
| 124 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, | 104 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, |
| 105 const std::string& account_id, |
| 125 net::URLRequestContextGetter* getter, | 106 net::URLRequestContextGetter* getter, |
| 126 const std::string& client_id, | 107 const std::string& client_id, |
| 127 const std::string& client_secret, | 108 const std::string& client_secret, |
| 128 const std::string& refresh_token, | 109 const std::string& refresh_token, |
| 129 const ScopeSet& scopes, | 110 const ScopeSet& scopes, |
| 130 base::WeakPtr<RequestImpl> waiting_request); | 111 base::WeakPtr<RequestImpl> waiting_request); |
| 131 virtual ~Fetcher(); | 112 virtual ~Fetcher(); |
| 132 | 113 |
| 133 // Add a request that is waiting for the result of this Fetcher. | 114 // Add a request that is waiting for the result of this Fetcher. |
| 134 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); | 115 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); |
| 135 | 116 |
| 136 // Returns count of waiting requests. | 117 // Returns count of waiting requests. |
| 137 size_t GetWaitingRequestCount() const; | 118 size_t GetWaitingRequestCount() const; |
| 138 | 119 |
| 139 void Cancel(); | 120 void Cancel(); |
| 140 | 121 |
| 141 const ScopeSet& GetScopeSet() const; | 122 const ScopeSet& GetScopeSet() const; |
| 142 const std::string& GetRefreshToken() const; | 123 const std::string& GetRefreshToken() const; |
| 143 const std::string& GetClientId() const; | 124 const std::string& GetClientId() const; |
| 125 const std::string& GetAccountId() const; |
| 144 | 126 |
| 145 // The error result from this fetcher. | 127 // The error result from this fetcher. |
| 146 const GoogleServiceAuthError& error() const { return error_; } | 128 const GoogleServiceAuthError& error() const { return error_; } |
| 147 | 129 |
| 148 protected: | 130 protected: |
| 149 // OAuth2AccessTokenConsumer | 131 // OAuth2AccessTokenConsumer |
| 150 virtual void OnGetTokenSuccess(const std::string& access_token, | 132 virtual void OnGetTokenSuccess(const std::string& access_token, |
| 151 const base::Time& expiration_date) OVERRIDE; | 133 const base::Time& expiration_date) OVERRIDE; |
| 152 virtual void OnGetTokenFailure( | 134 virtual void OnGetTokenFailure( |
| 153 const GoogleServiceAuthError& error) OVERRIDE; | 135 const GoogleServiceAuthError& error) OVERRIDE; |
| 154 | 136 |
| 155 private: | 137 private: |
| 156 Fetcher(OAuth2TokenService* oauth2_token_service, | 138 Fetcher(OAuth2TokenService* oauth2_token_service, |
| 139 const std::string& account_id, |
| 157 net::URLRequestContextGetter* getter, | 140 net::URLRequestContextGetter* getter, |
| 158 const std::string& client_id, | 141 const std::string& client_id, |
| 159 const std::string& client_secret, | 142 const std::string& client_secret, |
| 160 const std::string& refresh_token, | 143 const std::string& refresh_token, |
| 161 const OAuth2TokenService::ScopeSet& scopes, | 144 const OAuth2TokenService::ScopeSet& scopes, |
| 162 base::WeakPtr<RequestImpl> waiting_request); | 145 base::WeakPtr<RequestImpl> waiting_request); |
| 163 void Start(); | 146 void Start(); |
| 164 void InformWaitingRequests(); | 147 void InformWaitingRequests(); |
| 165 void InformWaitingRequestsAndDelete(); | 148 void InformWaitingRequestsAndDelete(); |
| 166 static bool ShouldRetry(const GoogleServiceAuthError& error); | 149 static bool ShouldRetry(const GoogleServiceAuthError& error); |
| 167 int64 ComputeExponentialBackOffMilliseconds(int retry_num); | 150 int64 ComputeExponentialBackOffMilliseconds(int retry_num); |
| 168 | 151 |
| 169 // |oauth2_token_service_| remains valid for the life of this Fetcher, since | 152 // |oauth2_token_service_| remains valid for the life of this Fetcher, since |
| 170 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is | 153 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is |
| 171 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess | 154 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess |
| 172 // (whichever comes first). | 155 // (whichever comes first). |
| 173 OAuth2TokenService* const oauth2_token_service_; | 156 OAuth2TokenService* const oauth2_token_service_; |
| 174 scoped_refptr<net::URLRequestContextGetter> getter_; | 157 scoped_refptr<net::URLRequestContextGetter> getter_; |
| 158 const std::string account_id_; |
| 175 const std::string refresh_token_; | 159 const std::string refresh_token_; |
| 176 const ScopeSet scopes_; | 160 const ScopeSet scopes_; |
| 177 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; | 161 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; |
| 178 | 162 |
| 179 int retry_number_; | 163 int retry_number_; |
| 180 base::OneShotTimer<Fetcher> retry_timer_; | 164 base::OneShotTimer<Fetcher> retry_timer_; |
| 181 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; | 165 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; |
| 182 | 166 |
| 183 // Variables that store fetch results. | 167 // Variables that store fetch results. |
| 184 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle | 168 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle |
| 185 // destruction. | 169 // destruction. |
| 186 GoogleServiceAuthError error_; | 170 GoogleServiceAuthError error_; |
| 187 std::string access_token_; | 171 std::string access_token_; |
| 188 base::Time expiration_date_; | 172 base::Time expiration_date_; |
| 189 | 173 |
| 190 // OAuth2 client id and secret. | 174 // OAuth2 client id and secret. |
| 191 std::string client_id_; | 175 std::string client_id_; |
| 192 std::string client_secret_; | 176 std::string client_secret_; |
| 193 | 177 |
| 194 DISALLOW_COPY_AND_ASSIGN(Fetcher); | 178 DISALLOW_COPY_AND_ASSIGN(Fetcher); |
| 195 }; | 179 }; |
| 196 | 180 |
| 197 // static | 181 // static |
| 198 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( | 182 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( |
| 199 OAuth2TokenService* oauth2_token_service, | 183 OAuth2TokenService* oauth2_token_service, |
| 184 const std::string& account_id, |
| 200 net::URLRequestContextGetter* getter, | 185 net::URLRequestContextGetter* getter, |
| 201 const std::string& client_id, | 186 const std::string& client_id, |
| 202 const std::string& client_secret, | 187 const std::string& client_secret, |
| 203 const std::string& refresh_token, | 188 const std::string& refresh_token, |
| 204 const OAuth2TokenService::ScopeSet& scopes, | 189 const OAuth2TokenService::ScopeSet& scopes, |
| 205 base::WeakPtr<RequestImpl> waiting_request) { | 190 base::WeakPtr<RequestImpl> waiting_request) { |
| 206 OAuth2TokenService::Fetcher* fetcher = new Fetcher( | 191 OAuth2TokenService::Fetcher* fetcher = new Fetcher( |
| 207 oauth2_token_service, | 192 oauth2_token_service, |
| 193 account_id, |
| 208 getter, | 194 getter, |
| 209 client_id, | 195 client_id, |
| 210 client_secret, | 196 client_secret, |
| 211 refresh_token, | 197 refresh_token, |
| 212 scopes, | 198 scopes, |
| 213 waiting_request); | 199 waiting_request); |
| 214 fetcher->Start(); | 200 fetcher->Start(); |
| 215 return fetcher; | 201 return fetcher; |
| 216 } | 202 } |
| 217 | 203 |
| 218 OAuth2TokenService::Fetcher::Fetcher( | 204 OAuth2TokenService::Fetcher::Fetcher( |
| 219 OAuth2TokenService* oauth2_token_service, | 205 OAuth2TokenService* oauth2_token_service, |
| 206 const std::string& account_id, |
| 220 net::URLRequestContextGetter* getter, | 207 net::URLRequestContextGetter* getter, |
| 221 const std::string& client_id, | 208 const std::string& client_id, |
| 222 const std::string& client_secret, | 209 const std::string& client_secret, |
| 223 const std::string& refresh_token, | 210 const std::string& refresh_token, |
| 224 const OAuth2TokenService::ScopeSet& scopes, | 211 const OAuth2TokenService::ScopeSet& scopes, |
| 225 base::WeakPtr<RequestImpl> waiting_request) | 212 base::WeakPtr<RequestImpl> waiting_request) |
| 226 : oauth2_token_service_(oauth2_token_service), | 213 : oauth2_token_service_(oauth2_token_service), |
| 227 getter_(getter), | 214 getter_(getter), |
| 215 account_id_(account_id), |
| 228 refresh_token_(refresh_token), | 216 refresh_token_(refresh_token), |
| 229 scopes_(scopes), | 217 scopes_(scopes), |
| 230 retry_number_(0), | 218 retry_number_(0), |
| 231 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), | 219 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), |
| 232 client_id_(client_id), | 220 client_id_(client_id), |
| 233 client_secret_(client_secret) { | 221 client_secret_(client_secret) { |
| 234 DCHECK(oauth2_token_service_); | 222 DCHECK(oauth2_token_service_); |
| 235 DCHECK(getter_.get()); | 223 DCHECK(getter_.get()); |
| 236 DCHECK(refresh_token_.length()); | 224 DCHECK(refresh_token_.length()); |
| 237 waiting_requests_.push_back(waiting_request); | 225 waiting_requests_.push_back(waiting_request); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 260 // Fetch completes. | 248 // Fetch completes. |
| 261 error_ = GoogleServiceAuthError::AuthErrorNone(); | 249 error_ = GoogleServiceAuthError::AuthErrorNone(); |
| 262 access_token_ = access_token; | 250 access_token_ = access_token; |
| 263 expiration_date_ = expiration_date; | 251 expiration_date_ = expiration_date; |
| 264 | 252 |
| 265 // Subclasses may override this method to skip caching in some cases, but | 253 // Subclasses may override this method to skip caching in some cases, but |
| 266 // we still inform all waiting Consumers of a successful token fetch below. | 254 // we still inform all waiting Consumers of a successful token fetch below. |
| 267 // This is intentional -- some consumers may need the token for cleanup | 255 // This is intentional -- some consumers may need the token for cleanup |
| 268 // tasks. https://chromiumcodereview.appspot.com/11312124/ | 256 // tasks. https://chromiumcodereview.appspot.com/11312124/ |
| 269 oauth2_token_service_->RegisterCacheEntry(client_id_, | 257 oauth2_token_service_->RegisterCacheEntry(client_id_, |
| 270 refresh_token_, | 258 account_id_, |
| 271 scopes_, | 259 scopes_, |
| 272 access_token_, | 260 access_token_, |
| 273 expiration_date_); | 261 expiration_date_); |
| 274 InformWaitingRequestsAndDelete(); | 262 InformWaitingRequestsAndDelete(); |
| 275 } | 263 } |
| 276 | 264 |
| 277 void OAuth2TokenService::Fetcher::OnGetTokenFailure( | 265 void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
| 278 const GoogleServiceAuthError& error) { | 266 const GoogleServiceAuthError& error) { |
| 279 fetcher_.reset(); | 267 fetcher_.reset(); |
| 280 | 268 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 } | 341 } |
| 354 | 342 |
| 355 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { | 343 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { |
| 356 return refresh_token_; | 344 return refresh_token_; |
| 357 } | 345 } |
| 358 | 346 |
| 359 const std::string& OAuth2TokenService::Fetcher::GetClientId() const { | 347 const std::string& OAuth2TokenService::Fetcher::GetClientId() const { |
| 360 return client_id_; | 348 return client_id_; |
| 361 } | 349 } |
| 362 | 350 |
| 351 const std::string& OAuth2TokenService::Fetcher::GetAccountId() const { |
| 352 return account_id_; |
| 353 } |
| 354 |
| 363 OAuth2TokenService::Request::Request() { | 355 OAuth2TokenService::Request::Request() { |
| 364 } | 356 } |
| 365 | 357 |
| 366 OAuth2TokenService::Request::~Request() { | 358 OAuth2TokenService::Request::~Request() { |
| 367 } | 359 } |
| 368 | 360 |
| 369 OAuth2TokenService::Consumer::Consumer() { | 361 OAuth2TokenService::Consumer::Consumer() { |
| 370 } | 362 } |
| 371 | 363 |
| 372 OAuth2TokenService::Consumer::~Consumer() { | 364 OAuth2TokenService::Consumer::~Consumer() { |
| 373 } | 365 } |
| 374 | 366 |
| 375 OAuth2TokenService::OAuth2TokenService() { | 367 OAuth2TokenService::OAuth2TokenService() { |
| 376 } | 368 } |
| 377 | 369 |
| 378 OAuth2TokenService::~OAuth2TokenService() { | 370 OAuth2TokenService::~OAuth2TokenService() { |
| 379 // Release all the pending fetchers. | 371 // Release all the pending fetchers. |
| 380 STLDeleteContainerPairSecondPointers( | 372 STLDeleteContainerPairSecondPointers( |
| 381 pending_fetchers_.begin(), pending_fetchers_.end()); | 373 pending_fetchers_.begin(), pending_fetchers_.end()); |
| 382 } | 374 } |
| 383 | 375 |
| 384 void OAuth2TokenService::AddObserver(Observer* observer) { | 376 void OAuth2TokenService::AddObserver(Observer* observer) { |
| 385 observer_list_.AddObserver(observer); | 377 observer_list_.AddObserver(observer); |
| 386 } | 378 } |
| 387 | 379 |
| 388 void OAuth2TokenService::RemoveObserver(Observer* observer) { | 380 void OAuth2TokenService::RemoveObserver(Observer* observer) { |
| 389 observer_list_.RemoveObserver(observer); | 381 observer_list_.RemoveObserver(observer); |
| 390 } | 382 } |
| 391 | 383 |
| 392 bool OAuth2TokenService::RefreshTokenIsAvailable() { | 384 bool OAuth2TokenService::RefreshTokenIsAvailable( |
| 393 return !GetRefreshToken().empty(); | 385 const std::string& account_id) { |
| 386 DCHECK(CalledOnValidThread()); |
| 387 return !GetRefreshToken(account_id).empty(); |
| 388 } |
| 389 |
| 390 std::vector<std::string> OAuth2TokenService::GetAccounts() { |
| 391 return std::vector<std::string>(); |
| 394 } | 392 } |
| 395 | 393 |
| 396 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( | 394 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
| 395 const std::string& account_id, |
| 397 const OAuth2TokenService::ScopeSet& scopes, | 396 const OAuth2TokenService::ScopeSet& scopes, |
| 398 OAuth2TokenService::Consumer* consumer) { | 397 OAuth2TokenService::Consumer* consumer) { |
| 399 return StartRequestForClientWithContext( | 398 return StartRequestForClientWithContext( |
| 399 account_id, |
| 400 GetRequestContext(), | 400 GetRequestContext(), |
| 401 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | 401 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
| 402 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), | 402 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), |
| 403 scopes, | 403 scopes, |
| 404 consumer); | 404 consumer); |
| 405 } | 405 } |
| 406 | 406 |
| 407 scoped_ptr<OAuth2TokenService::Request> | 407 scoped_ptr<OAuth2TokenService::Request> |
| 408 OAuth2TokenService::StartRequestForClient( | 408 OAuth2TokenService::StartRequestForClient( |
| 409 const std::string& account_id, |
| 409 const std::string& client_id, | 410 const std::string& client_id, |
| 410 const std::string& client_secret, | 411 const std::string& client_secret, |
| 411 const OAuth2TokenService::ScopeSet& scopes, | 412 const OAuth2TokenService::ScopeSet& scopes, |
| 412 OAuth2TokenService::Consumer* consumer) { | 413 OAuth2TokenService::Consumer* consumer) { |
| 413 return StartRequestForClientWithContext( | 414 return StartRequestForClientWithContext( |
| 415 account_id, |
| 414 GetRequestContext(), | 416 GetRequestContext(), |
| 415 client_id, | 417 client_id, |
| 416 client_secret, | 418 client_secret, |
| 417 scopes, | 419 scopes, |
| 418 consumer); | 420 consumer); |
| 419 } | 421 } |
| 420 | 422 |
| 421 scoped_ptr<OAuth2TokenService::Request> | 423 scoped_ptr<OAuth2TokenService::Request> |
| 422 OAuth2TokenService::StartRequestWithContext( | 424 OAuth2TokenService::StartRequestWithContext( |
| 425 const std::string& account_id, |
| 423 net::URLRequestContextGetter* getter, | 426 net::URLRequestContextGetter* getter, |
| 424 const ScopeSet& scopes, | 427 const ScopeSet& scopes, |
| 425 Consumer* consumer) { | 428 Consumer* consumer) { |
| 426 return StartRequestForClientWithContext( | 429 return StartRequestForClientWithContext( |
| 430 account_id, |
| 427 getter, | 431 getter, |
| 428 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | 432 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
| 429 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), | 433 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), |
| 430 scopes, | 434 scopes, |
| 431 consumer); | 435 consumer); |
| 432 } | 436 } |
| 433 | 437 |
| 434 scoped_ptr<OAuth2TokenService::Request> | 438 scoped_ptr<OAuth2TokenService::Request> |
| 435 OAuth2TokenService::StartRequestForClientWithContext( | 439 OAuth2TokenService::StartRequestForClientWithContext( |
| 440 const std::string& account_id, |
| 436 net::URLRequestContextGetter* getter, | 441 net::URLRequestContextGetter* getter, |
| 437 const std::string& client_id, | 442 const std::string& client_id, |
| 438 const std::string& client_secret, | 443 const std::string& client_secret, |
| 439 const ScopeSet& scopes, | 444 const ScopeSet& scopes, |
| 440 Consumer* consumer) { | 445 Consumer* consumer) { |
| 441 DCHECK(CalledOnValidThread()); | 446 DCHECK(CalledOnValidThread()); |
| 442 | 447 |
| 443 scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); | 448 scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); |
| 444 | 449 |
| 445 if (!RefreshTokenIsAvailable()) { | 450 if (!RefreshTokenIsAvailable(account_id)) { |
| 446 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 451 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 447 &RequestImpl::InformConsumer, | 452 &RequestImpl::InformConsumer, |
| 448 request->AsWeakPtr(), | 453 request->AsWeakPtr(), |
| 449 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), | 454 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), |
| 450 std::string(), | 455 std::string(), |
| 451 base::Time())); | 456 base::Time())); |
| 452 return request.PassAs<Request>(); | 457 return request.PassAs<Request>(); |
| 453 } | 458 } |
| 454 | 459 |
| 455 ClientScopeSet client_scopes(client_id, scopes); | 460 RequestParameters request_parameters(client_id, |
| 456 if (HasCacheEntry(client_scopes)) { | 461 account_id, |
| 457 StartCacheLookupRequest(request.get(), client_scopes, consumer); | 462 scopes); |
| 463 if (HasCacheEntry(request_parameters)) { |
| 464 StartCacheLookupRequest(request.get(), request_parameters, consumer); |
| 458 } else { | 465 } else { |
| 459 FetchOAuth2Token(request.get(), | 466 FetchOAuth2Token(request.get(), |
| 467 account_id, |
| 460 getter, | 468 getter, |
| 461 client_id, | 469 client_id, |
| 462 client_secret, | 470 client_secret, |
| 463 scopes); | 471 scopes); |
| 464 } | 472 } |
| 465 return request.PassAs<Request>(); | 473 return request.PassAs<Request>(); |
| 466 } | 474 } |
| 467 | 475 |
| 468 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, | 476 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, |
| 477 const std::string& account_id, |
| 469 net::URLRequestContextGetter* getter, | 478 net::URLRequestContextGetter* getter, |
| 470 const std::string& client_id, | 479 const std::string& client_id, |
| 471 const std::string& client_secret, | 480 const std::string& client_secret, |
| 472 const ScopeSet& scopes) { | 481 const ScopeSet& scopes) { |
| 473 std::string refresh_token = GetRefreshToken(); | 482 std::string refresh_token = GetRefreshToken(account_id); |
| 474 | 483 |
| 475 // If there is already a pending fetcher for |scopes| and |refresh_token|, | 484 // If there is already a pending fetcher for |scopes| and |account_id|, |
| 476 // simply register this |request| for those results rather than starting | 485 // simply register this |request| for those results rather than starting |
| 477 // a new fetcher. | 486 // a new fetcher. |
| 478 FetchParameters fetch_parameters = FetchParameters(client_id, | 487 RequestParameters request_parameters = RequestParameters(client_id, |
| 479 refresh_token, | 488 account_id, |
| 480 scopes); | 489 scopes); |
| 481 std::map<FetchParameters, Fetcher*>::iterator iter = | 490 std::map<RequestParameters, Fetcher*>::iterator iter = |
| 482 pending_fetchers_.find(fetch_parameters); | 491 pending_fetchers_.find(request_parameters); |
| 483 if (iter != pending_fetchers_.end()) { | 492 if (iter != pending_fetchers_.end()) { |
| 484 iter->second->AddWaitingRequest(request->AsWeakPtr()); | 493 iter->second->AddWaitingRequest(request->AsWeakPtr()); |
| 485 return; | 494 return; |
| 486 } | 495 } |
| 487 | 496 |
| 488 pending_fetchers_[fetch_parameters] = | 497 pending_fetchers_[request_parameters] = |
| 489 Fetcher::CreateAndStart(this, | 498 Fetcher::CreateAndStart(this, |
| 499 account_id, |
| 490 getter, | 500 getter, |
| 491 client_id, | 501 client_id, |
| 492 client_secret, | 502 client_secret, |
| 493 refresh_token, | 503 refresh_token, |
| 494 scopes, | 504 scopes, |
| 495 request->AsWeakPtr()); | 505 request->AsWeakPtr()); |
| 496 } | 506 } |
| 497 | 507 |
| 498 void OAuth2TokenService::StartCacheLookupRequest( | 508 void OAuth2TokenService::StartCacheLookupRequest( |
| 499 RequestImpl* request, | 509 RequestImpl* request, |
| 500 const OAuth2TokenService::ClientScopeSet& client_scopes, | 510 const OAuth2TokenService::RequestParameters& request_parameters, |
| 501 OAuth2TokenService::Consumer* consumer) { | 511 OAuth2TokenService::Consumer* consumer) { |
| 502 CHECK(HasCacheEntry(client_scopes)); | 512 CHECK(HasCacheEntry(request_parameters)); |
| 503 const CacheEntry* cache_entry = GetCacheEntry(client_scopes); | 513 const CacheEntry* cache_entry = GetCacheEntry(request_parameters); |
| 504 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 514 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 505 &RequestImpl::InformConsumer, | 515 &RequestImpl::InformConsumer, |
| 506 request->AsWeakPtr(), | 516 request->AsWeakPtr(), |
| 507 GoogleServiceAuthError(GoogleServiceAuthError::NONE), | 517 GoogleServiceAuthError(GoogleServiceAuthError::NONE), |
| 508 cache_entry->access_token, | 518 cache_entry->access_token, |
| 509 cache_entry->expiration_date)); | 519 cache_entry->expiration_date)); |
| 510 } | 520 } |
| 511 | 521 |
| 512 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes, | 522 void OAuth2TokenService::InvalidateToken(const std::string& account_id, |
| 513 const std::string& invalid_token) { | 523 const ScopeSet& scopes, |
| 524 const std::string& access_token) { |
| 525 InvalidateOAuth2Token(account_id, |
| 526 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
| 527 scopes, |
| 528 access_token); |
| 529 } |
| 530 |
| 531 void OAuth2TokenService::InvalidateTokenForClient( |
| 532 const std::string& account_id, |
| 533 const std::string& client_id, |
| 534 const ScopeSet& scopes, |
| 535 const std::string& access_token) { |
| 536 InvalidateOAuth2Token(account_id, client_id, scopes, access_token); |
| 537 } |
| 538 |
| 539 void OAuth2TokenService::InvalidateOAuth2Token( |
| 540 const std::string& account_id, |
| 541 const std::string& client_id, |
| 542 const ScopeSet& scopes, |
| 543 const std::string& access_token) { |
| 514 DCHECK(CalledOnValidThread()); | 544 DCHECK(CalledOnValidThread()); |
| 515 RemoveCacheEntry( | 545 RemoveCacheEntry( |
| 516 ClientScopeSet(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | 546 RequestParameters(client_id, |
| 517 scopes), | 547 account_id, |
| 518 invalid_token); | 548 scopes), |
| 549 access_token); |
| 519 } | 550 } |
| 520 | 551 |
| 521 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { | 552 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { |
| 522 DCHECK(CalledOnValidThread()); | 553 DCHECK(CalledOnValidThread()); |
| 523 | 554 |
| 524 // Update the auth error state so auth errors are appropriately communicated | 555 // Update the auth error state so auth errors are appropriately communicated |
| 525 // to the user. | 556 // to the user. |
| 526 UpdateAuthError(fetcher->error()); | 557 UpdateAuthError(fetcher->GetAccountId(), fetcher->error()); |
| 527 | 558 |
| 528 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh | 559 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh |
| 529 // token and scope set. This is guaranteed as follows; here a Fetcher is said | 560 // token and scope set. This is guaranteed as follows; here a Fetcher is said |
| 530 // to be uncompleted if it has not finished calling back | 561 // to be uncompleted if it has not finished calling back |
| 531 // OAuth2TokenService::OnFetchComplete(). | 562 // OAuth2TokenService::OnFetchComplete(). |
| 532 // | 563 // |
| 533 // (1) All the live Fetchers are created by this service. | 564 // (1) All the live Fetchers are created by this service. |
| 534 // This is because (1) all the live Fetchers are created by a live | 565 // This is because (1) all the live Fetchers are created by a live |
| 535 // service, as all the fetchers created by a service are destructed in the | 566 // service, as all the fetchers created by a service are destructed in the |
| 536 // service's dtor. | 567 // service's dtor. |
| 537 // | 568 // |
| 538 // (2) All the uncompleted Fetchers created by this service are recorded in | 569 // (2) All the uncompleted Fetchers created by this service are recorded in |
| 539 // |pending_fetchers_|. | 570 // |pending_fetchers_|. |
| 540 // This is because (1) all the created Fetchers are added to | 571 // This is because (1) all the created Fetchers are added to |
| 541 // |pending_fetchers_| (in method StartRequest()) and (2) method | 572 // |pending_fetchers_| (in method StartRequest()) and (2) method |
| 542 // OnFetchComplete() is the only place where a Fetcher is erased from | 573 // OnFetchComplete() is the only place where a Fetcher is erased from |
| 543 // |pending_fetchers_|. Note no Fetcher is erased in method | 574 // |pending_fetchers_|. Note no Fetcher is erased in method |
| 544 // StartRequest(). | 575 // StartRequest(). |
| 545 // | 576 // |
| 546 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its | 577 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its |
| 547 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in | 578 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in |
| 548 // method StartRequest(). | 579 // method StartRequest(). |
| 549 // | 580 // |
| 550 // When this method is called, |fetcher| is alive and uncompleted. | 581 // When this method is called, |fetcher| is alive and uncompleted. |
| 551 // By (1), |fetcher| is created by this service. | 582 // By (1), |fetcher| is created by this service. |
| 552 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. | 583 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. |
| 553 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. | 584 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. |
| 554 std::map<FetchParameters, Fetcher*>::iterator iter = | 585 std::map<RequestParameters, Fetcher*>::iterator iter = |
| 555 pending_fetchers_.find(FetchParameters( | 586 pending_fetchers_.find(RequestParameters( |
| 556 fetcher->GetClientId(), | 587 fetcher->GetClientId(), |
| 557 fetcher->GetRefreshToken(), | 588 fetcher->GetAccountId(), |
| 558 fetcher->GetScopeSet())); | 589 fetcher->GetScopeSet())); |
| 559 DCHECK(iter != pending_fetchers_.end()); | 590 DCHECK(iter != pending_fetchers_.end()); |
| 560 DCHECK_EQ(fetcher, iter->second); | 591 DCHECK_EQ(fetcher, iter->second); |
| 561 pending_fetchers_.erase(iter); | 592 pending_fetchers_.erase(iter); |
| 562 } | 593 } |
| 563 | 594 |
| 564 bool OAuth2TokenService::HasCacheEntry( | 595 bool OAuth2TokenService::HasCacheEntry( |
| 565 const ClientScopeSet& client_scopes) { | 596 const RequestParameters& request_parameters) { |
| 566 const CacheEntry* cache_entry = GetCacheEntry(client_scopes); | 597 const CacheEntry* cache_entry = GetCacheEntry(request_parameters); |
| 567 return cache_entry && cache_entry->access_token.length(); | 598 return cache_entry && cache_entry->access_token.length(); |
| 568 } | 599 } |
| 569 | 600 |
| 570 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( | 601 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( |
| 571 const ClientScopeSet& client_scopes) { | 602 const RequestParameters& request_parameters) { |
| 572 DCHECK(CalledOnValidThread()); | 603 DCHECK(CalledOnValidThread()); |
| 573 TokenCache::iterator token_iterator = token_cache_.find(client_scopes); | 604 TokenCache::iterator token_iterator = token_cache_.find(request_parameters); |
| 574 if (token_iterator == token_cache_.end()) | 605 if (token_iterator == token_cache_.end()) |
| 575 return NULL; | 606 return NULL; |
| 576 if (token_iterator->second.expiration_date <= base::Time::Now()) { | 607 if (token_iterator->second.expiration_date <= base::Time::Now()) { |
| 577 token_cache_.erase(token_iterator); | 608 token_cache_.erase(token_iterator); |
| 578 return NULL; | 609 return NULL; |
| 579 } | 610 } |
| 580 return &token_iterator->second; | 611 return &token_iterator->second; |
| 581 } | 612 } |
| 582 | 613 |
| 583 bool OAuth2TokenService::RemoveCacheEntry( | 614 bool OAuth2TokenService::RemoveCacheEntry( |
| 584 const ClientScopeSet& client_scopes, | 615 const RequestParameters& request_parameters, |
| 585 const std::string& token_to_remove) { | 616 const std::string& token_to_remove) { |
| 586 DCHECK(CalledOnValidThread()); | 617 DCHECK(CalledOnValidThread()); |
| 587 TokenCache::iterator token_iterator = token_cache_.find(client_scopes); | 618 TokenCache::iterator token_iterator = token_cache_.find(request_parameters); |
| 588 if (token_iterator != token_cache_.end() && | 619 if (token_iterator != token_cache_.end() && |
| 589 token_iterator->second.access_token == token_to_remove) { | 620 token_iterator->second.access_token == token_to_remove) { |
| 590 token_cache_.erase(token_iterator); | 621 token_cache_.erase(token_iterator); |
| 591 return true; | 622 return true; |
| 592 } | 623 } |
| 593 return false; | 624 return false; |
| 594 } | 625 } |
| 595 | 626 |
| 596 void OAuth2TokenService::RegisterCacheEntry( | 627 void OAuth2TokenService::RegisterCacheEntry( |
| 597 const std::string& client_id, | 628 const std::string& client_id, |
| 598 const std::string& refresh_token, | 629 const std::string& account_id, |
| 599 const OAuth2TokenService::ScopeSet& scopes, | 630 const OAuth2TokenService::ScopeSet& scopes, |
| 600 const std::string& access_token, | 631 const std::string& access_token, |
| 601 const base::Time& expiration_date) { | 632 const base::Time& expiration_date) { |
| 602 DCHECK(CalledOnValidThread()); | 633 DCHECK(CalledOnValidThread()); |
| 603 | 634 |
| 604 CacheEntry& token = token_cache_[ClientScopeSet(client_id, | 635 CacheEntry& token = token_cache_[RequestParameters(client_id, |
| 605 scopes)]; | 636 account_id, |
| 637 scopes)]; |
| 606 token.access_token = access_token; | 638 token.access_token = access_token; |
| 607 token.expiration_date = expiration_date; | 639 token.expiration_date = expiration_date; |
| 608 } | 640 } |
| 609 | 641 |
| 610 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { | 642 void OAuth2TokenService::UpdateAuthError( |
| 643 const std::string& account_id, |
| 644 const GoogleServiceAuthError& error) { |
| 611 // Default implementation does nothing. | 645 // Default implementation does nothing. |
| 612 } | 646 } |
| 613 | 647 |
| 614 void OAuth2TokenService::ClearCache() { | 648 void OAuth2TokenService::ClearCache() { |
| 615 DCHECK(CalledOnValidThread()); | 649 DCHECK(CalledOnValidThread()); |
| 616 token_cache_.clear(); | 650 token_cache_.clear(); |
| 617 } | 651 } |
| 618 | 652 |
| 653 void OAuth2TokenService::ClearCacheForAccount(const std::string& account_id) { |
| 654 DCHECK(CalledOnValidThread()); |
| 655 for (TokenCache::iterator iter = token_cache_.begin(); |
| 656 iter != token_cache_.end(); |
| 657 /* iter incremented in body */) { |
| 658 if (iter->first.account_id == account_id) { |
| 659 token_cache_.erase(iter++); |
| 660 } else { |
| 661 ++iter; |
| 662 } |
| 663 } |
| 664 } |
| 665 |
| 619 void OAuth2TokenService::CancelAllRequests() { | 666 void OAuth2TokenService::CancelAllRequests() { |
| 620 std::vector<Fetcher*> fetchers_to_cancel; | 667 std::vector<Fetcher*> fetchers_to_cancel; |
| 621 for (std::map<FetchParameters, Fetcher*>::iterator iter = | 668 for (std::map<RequestParameters, Fetcher*>::iterator iter = |
| 622 pending_fetchers_.begin(); | 669 pending_fetchers_.begin(); |
| 623 iter != pending_fetchers_.end(); | 670 iter != pending_fetchers_.end(); |
| 624 ++iter) { | 671 ++iter) { |
| 625 fetchers_to_cancel.push_back(iter->second); | 672 fetchers_to_cancel.push_back(iter->second); |
| 626 } | 673 } |
| 627 CancelFetchers(fetchers_to_cancel); | 674 CancelFetchers(fetchers_to_cancel); |
| 628 } | 675 } |
| 629 | 676 |
| 630 void OAuth2TokenService::CancelRequestsForToken( | 677 void OAuth2TokenService::CancelRequestsForAccount( |
| 631 const std::string& refresh_token) { | 678 const std::string& account_id) { |
| 632 std::vector<Fetcher*> fetchers_to_cancel; | 679 std::vector<Fetcher*> fetchers_to_cancel; |
| 633 for (std::map<FetchParameters, Fetcher*>::iterator iter = | 680 for (std::map<RequestParameters, Fetcher*>::iterator iter = |
| 634 pending_fetchers_.begin(); | 681 pending_fetchers_.begin(); |
| 635 iter != pending_fetchers_.end(); | 682 iter != pending_fetchers_.end(); |
| 636 ++iter) { | 683 ++iter) { |
| 637 if (iter->first.refresh_token == refresh_token) | 684 if (iter->first.account_id == account_id) |
| 638 fetchers_to_cancel.push_back(iter->second); | 685 fetchers_to_cancel.push_back(iter->second); |
| 639 } | 686 } |
| 640 CancelFetchers(fetchers_to_cancel); | 687 CancelFetchers(fetchers_to_cancel); |
| 641 } | 688 } |
| 642 | 689 |
| 643 void OAuth2TokenService::CancelFetchers( | 690 void OAuth2TokenService::CancelFetchers( |
| 644 std::vector<Fetcher*> fetchers_to_cancel) { | 691 std::vector<Fetcher*> fetchers_to_cancel) { |
| 645 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = | 692 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = |
| 646 fetchers_to_cancel.begin(); | 693 fetchers_to_cancel.begin(); |
| 647 iter != fetchers_to_cancel.end(); | 694 iter != fetchers_to_cancel.end(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 659 void OAuth2TokenService::FireRefreshTokenRevoked( | 706 void OAuth2TokenService::FireRefreshTokenRevoked( |
| 660 const std::string& account_id) { | 707 const std::string& account_id) { |
| 661 FOR_EACH_OBSERVER(Observer, observer_list_, | 708 FOR_EACH_OBSERVER(Observer, observer_list_, |
| 662 OnRefreshTokenRevoked(account_id)); | 709 OnRefreshTokenRevoked(account_id)); |
| 663 } | 710 } |
| 664 | 711 |
| 665 void OAuth2TokenService::FireRefreshTokensLoaded() { | 712 void OAuth2TokenService::FireRefreshTokensLoaded() { |
| 666 FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded()); | 713 FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded()); |
| 667 } | 714 } |
| 668 | 715 |
| 669 void OAuth2TokenService::FireRefreshTokensCleared() { | |
| 670 FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensCleared()); | |
| 671 } | |
| 672 | |
| 673 int OAuth2TokenService::cache_size_for_testing() const { | 716 int OAuth2TokenService::cache_size_for_testing() const { |
| 674 return token_cache_.size(); | 717 return token_cache_.size(); |
| 675 } | 718 } |
| 676 | 719 |
| 677 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( | 720 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( |
| 678 int max_retries) { | 721 int max_retries) { |
| 679 DCHECK(CalledOnValidThread()); | 722 DCHECK(CalledOnValidThread()); |
| 680 max_fetch_retry_num_ = max_retries; | 723 max_fetch_retry_num_ = max_retries; |
| 681 } | 724 } |
| 682 | 725 |
| 683 size_t OAuth2TokenService::GetNumPendingRequestsForTesting( | 726 size_t OAuth2TokenService::GetNumPendingRequestsForTesting( |
| 684 const std::string& client_id, | 727 const std::string& client_id, |
| 685 const std::string& refresh_token, | 728 const std::string& account_id, |
| 686 const ScopeSet& scopes) const { | 729 const ScopeSet& scopes) const { |
| 687 PendingFetcherMap::const_iterator iter = pending_fetchers_.find( | 730 PendingFetcherMap::const_iterator iter = pending_fetchers_.find( |
| 688 OAuth2TokenService::FetchParameters( | 731 OAuth2TokenService::RequestParameters( |
| 689 client_id, | 732 client_id, |
| 690 refresh_token, | 733 account_id, |
| 691 scopes)); | 734 scopes)); |
| 692 return iter == pending_fetchers_.end() ? | 735 return iter == pending_fetchers_.end() ? |
| 693 0 : iter->second->GetWaitingRequestCount(); | 736 0 : iter->second->GetWaitingRequestCount(); |
| 694 } | 737 } |
| OLD | NEW |