oauth2_access_token_manager.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. // Copyright 2019 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. #include "google_apis/gaia/oauth2_access_token_manager.h"
  5. #include "base/memory/ptr_util.h"
  6. #include "base/memory/raw_ptr.h"
  7. #include "base/metrics/histogram_macros.h"
  8. #include "base/observer_list.h"
  9. #include "base/rand_util.h"
  10. #include "base/threading/thread_task_runner_handle.h"
  11. #include "base/time/time.h"
  12. #include "base/timer/timer.h"
  13. #include "google_apis/gaia/gaia_urls.h"
  14. #include "google_apis/gaia/oauth2_access_token_fetcher.h"
  15. #include "services/network/public/cpp/shared_url_loader_factory.h"
  16. namespace {
  17. void RecordOAuth2TokenFetchResult(GoogleServiceAuthError::State state) {
  18. UMA_HISTOGRAM_ENUMERATION("Signin.OAuth2TokenGetResult", state,
  19. GoogleServiceAuthError::NUM_STATES);
  20. }
  21. } // namespace
  22. int OAuth2AccessTokenManager::max_fetch_retry_num_ = 5;
  23. OAuth2AccessTokenManager::Delegate::Delegate() = default;
  24. OAuth2AccessTokenManager::Delegate::~Delegate() = default;
  25. bool OAuth2AccessTokenManager::Delegate::FixRequestErrorIfPossible() {
  26. return false;
  27. }
  28. scoped_refptr<network::SharedURLLoaderFactory>
  29. OAuth2AccessTokenManager::Delegate::GetURLLoaderFactory() const {
  30. return nullptr;
  31. }
  32. bool OAuth2AccessTokenManager::Delegate::HandleAccessTokenFetch(
  33. RequestImpl* request,
  34. const CoreAccountId& account_id,
  35. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  36. const std::string& client_id,
  37. const std::string& client_secret,
  38. const ScopeSet& scopes) {
  39. return false;
  40. }
  41. OAuth2AccessTokenManager::Request::Request() {}
  42. OAuth2AccessTokenManager::Request::~Request() {}
  43. OAuth2AccessTokenManager::Consumer::Consumer(const std::string& id) : id_(id) {}
  44. OAuth2AccessTokenManager::Consumer::~Consumer() {}
  45. OAuth2AccessTokenManager::RequestImpl::RequestImpl(
  46. const CoreAccountId& account_id,
  47. Consumer* consumer)
  48. : account_id_(account_id), consumer_(consumer) {}
  49. OAuth2AccessTokenManager::RequestImpl::~RequestImpl() {
  50. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  51. }
  52. CoreAccountId OAuth2AccessTokenManager::RequestImpl::GetAccountId() const {
  53. return account_id_;
  54. }
  55. std::string OAuth2AccessTokenManager::RequestImpl::GetConsumerId() const {
  56. return consumer_->id();
  57. }
  58. void OAuth2AccessTokenManager::RequestImpl::InformConsumer(
  59. const GoogleServiceAuthError& error,
  60. const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  61. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  62. if (error.state() == GoogleServiceAuthError::NONE)
  63. consumer_->OnGetTokenSuccess(this, token_response);
  64. else
  65. consumer_->OnGetTokenFailure(this, error);
  66. }
  67. OAuth2AccessTokenManager::RequestParameters::RequestParameters(
  68. const std::string& client_id,
  69. const CoreAccountId& account_id,
  70. const ScopeSet& scopes)
  71. : client_id(client_id), account_id(account_id), scopes(scopes) {}
  72. OAuth2AccessTokenManager::RequestParameters::RequestParameters(
  73. const RequestParameters& other) = default;
  74. OAuth2AccessTokenManager::RequestParameters::~RequestParameters() {}
  75. bool OAuth2AccessTokenManager::RequestParameters::operator<(
  76. const RequestParameters& p) const {
  77. if (client_id < p.client_id)
  78. return true;
  79. else if (p.client_id < client_id)
  80. return false;
  81. if (account_id < p.account_id)
  82. return true;
  83. else if (p.account_id < account_id)
  84. return false;
  85. return scopes < p.scopes;
  86. }
  87. // Class that fetches an OAuth2 access token for a given account id and set of
  88. // scopes.
  89. //
  90. // It aims to meet OAuth2AccessTokenManager's requirements on token fetching.
  91. // Retry mechanism is used to handle failures.
  92. //
  93. // To use this class, call CreateAndStart() to create and start a Fetcher.
  94. //
  95. // The Fetcher will call back the token manager by calling
  96. // OAuth2AccessTokenManager::OnFetchComplete() when it completes fetching, if
  97. // it is not destroyed before it completes fetching; if the Fetcher is destroyed
  98. // before it completes fetching, the token manager will never be called back.
  99. // The Fetcher destroys itself after calling back the manager when it finishes
  100. // fetching.
  101. //
  102. // Requests that are waiting for the fetching results of this Fetcher can be
  103. // added to the Fetcher by calling
  104. // OAuth2AccessTokenManager::Fetcher::AddWaitingRequest() before the Fetcher
  105. // completes fetching.
  106. //
  107. // The waiting requests are taken as weak pointers and they can be deleted.
  108. // They will be called back with the result when either the Fetcher completes
  109. // fetching or is destroyed, whichever comes first. In the latter case, the
  110. // waiting requests will be called back with an error.
  111. //
  112. // The OAuth2AccessTokenManager and the waiting requests will never be called
  113. // back on the same turn of the message loop as when the fetcher is started,
  114. // even if an immediate error occurred.
  115. class OAuth2AccessTokenManager::Fetcher : public OAuth2AccessTokenConsumer {
  116. public:
  117. // Creates a Fetcher and starts fetching an OAuth2 access token for
  118. // |account_id| and |scopes| in the request context obtained by |getter|.
  119. // The given |oauth2_access_token_manager| will be informed when fetching is
  120. // done.
  121. static std::unique_ptr<OAuth2AccessTokenManager::Fetcher> CreateAndStart(
  122. OAuth2AccessTokenManager* oauth2_access_token_manager,
  123. const CoreAccountId& account_id,
  124. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  125. const std::string& client_id,
  126. const std::string& client_secret,
  127. const ScopeSet& scopes,
  128. const std::string& consumer_name,
  129. base::WeakPtr<RequestImpl> waiting_request);
  130. Fetcher(const Fetcher&) = delete;
  131. Fetcher& operator=(const Fetcher&) = delete;
  132. ~Fetcher() override;
  133. // Add a request that is waiting for the result of this Fetcher.
  134. void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request);
  135. // Returns count of waiting requests.
  136. size_t GetWaitingRequestCount() const;
  137. const std::vector<base::WeakPtr<RequestImpl>>& waiting_requests() const {
  138. return waiting_requests_;
  139. }
  140. void Cancel();
  141. const ScopeSet& GetScopeSet() const;
  142. const std::string& GetClientId() const;
  143. const CoreAccountId& GetAccountId() const;
  144. // The error result from this fetcher.
  145. const GoogleServiceAuthError& error() const { return error_; }
  146. protected:
  147. // OAuth2AccessTokenConsumer
  148. void OnGetTokenSuccess(
  149. const OAuth2AccessTokenConsumer::TokenResponse& token_response) override;
  150. void OnGetTokenFailure(const GoogleServiceAuthError& error) override;
  151. std::string GetConsumerName() const override;
  152. private:
  153. Fetcher(OAuth2AccessTokenManager* oauth2_access_token_manager,
  154. const CoreAccountId& account_id,
  155. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  156. const std::string& client_id,
  157. const std::string& client_secret,
  158. const ScopeSet& scopes,
  159. const std::string& consumer_name,
  160. base::WeakPtr<RequestImpl> waiting_request);
  161. void Start();
  162. void InformWaitingRequests();
  163. void InformWaitingRequestsAndDelete();
  164. bool ShouldRetry(const GoogleServiceAuthError& error) const;
  165. int64_t ComputeExponentialBackOffMilliseconds(int retry_num);
  166. // Attempts to retry the fetch if possible. This is possible if the retry
  167. // count has not been exceeded. Returns true if a retry has been restarted
  168. // and false otherwise.
  169. bool RetryIfPossible(const GoogleServiceAuthError& error);
  170. // |oauth2_access_token_manager_| remains valid for the life of this
  171. // Fetcher, since this Fetcher is destructed in the dtor of the
  172. // OAuth2AccessTokenManager or is scheduled for deletion at the end of
  173. // OnGetTokenFailure/OnGetTokenSuccess (whichever comes first).
  174. const raw_ptr<OAuth2AccessTokenManager> oauth2_access_token_manager_;
  175. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  176. const CoreAccountId account_id_;
  177. const ScopeSet scopes_;
  178. const std::string consumer_name_;
  179. std::vector<base::WeakPtr<RequestImpl>> waiting_requests_;
  180. int retry_number_;
  181. base::OneShotTimer retry_timer_;
  182. std::unique_ptr<OAuth2AccessTokenFetcher> fetcher_;
  183. // Variables that store fetch results.
  184. // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
  185. // destruction.
  186. GoogleServiceAuthError error_;
  187. OAuth2AccessTokenConsumer::TokenResponse token_response_;
  188. // OAuth2 client id and secret.
  189. std::string client_id_;
  190. std::string client_secret_;
  191. // Ensures that the fetcher is deleted only once.
  192. bool scheduled_for_deletion_ = false;
  193. };
  194. // static
  195. std::unique_ptr<OAuth2AccessTokenManager::Fetcher>
  196. OAuth2AccessTokenManager::Fetcher::CreateAndStart(
  197. OAuth2AccessTokenManager* oauth2_access_token_manager,
  198. const CoreAccountId& account_id,
  199. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  200. const std::string& client_id,
  201. const std::string& client_secret,
  202. const ScopeSet& scopes,
  203. const std::string& consumer_name,
  204. base::WeakPtr<RequestImpl> waiting_request) {
  205. std::unique_ptr<OAuth2AccessTokenManager::Fetcher> fetcher =
  206. base::WrapUnique(new Fetcher(oauth2_access_token_manager, account_id,
  207. url_loader_factory, client_id, client_secret,
  208. scopes, consumer_name, waiting_request));
  209. fetcher->Start();
  210. return fetcher;
  211. }
  212. OAuth2AccessTokenManager::Fetcher::Fetcher(
  213. OAuth2AccessTokenManager* oauth2_access_token_manager,
  214. const CoreAccountId& account_id,
  215. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  216. const std::string& client_id,
  217. const std::string& client_secret,
  218. const ScopeSet& scopes,
  219. const std::string& consumer_name,
  220. base::WeakPtr<RequestImpl> waiting_request)
  221. : oauth2_access_token_manager_(oauth2_access_token_manager),
  222. url_loader_factory_(url_loader_factory),
  223. account_id_(account_id),
  224. scopes_(scopes),
  225. consumer_name_(consumer_name),
  226. retry_number_(0),
  227. error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
  228. client_id_(client_id),
  229. client_secret_(client_secret) {
  230. DCHECK(oauth2_access_token_manager_);
  231. waiting_requests_.push_back(waiting_request);
  232. }
  233. OAuth2AccessTokenManager::Fetcher::~Fetcher() {
  234. // Inform the waiting requests if it has not done so.
  235. if (waiting_requests_.size())
  236. InformWaitingRequests();
  237. }
  238. void OAuth2AccessTokenManager::Fetcher::Start() {
  239. fetcher_ = oauth2_access_token_manager_->CreateAccessTokenFetcher(
  240. account_id_, url_loader_factory_, this);
  241. DCHECK(fetcher_);
  242. // Stop the timer before starting the fetch, as defense in depth against the
  243. // fetcher calling us back synchronously (which might restart the timer).
  244. retry_timer_.Stop();
  245. fetcher_->Start(client_id_, client_secret_,
  246. std::vector<std::string>(scopes_.begin(), scopes_.end()));
  247. }
  248. void OAuth2AccessTokenManager::Fetcher::OnGetTokenSuccess(
  249. const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  250. CHECK(fetcher_);
  251. fetcher_.reset();
  252. RecordOAuth2TokenFetchResult(GoogleServiceAuthError::NONE);
  253. // Fetch completes.
  254. error_ = GoogleServiceAuthError::AuthErrorNone();
  255. token_response_ = token_response;
  256. // Delegates may override this method to skip caching in some cases, but
  257. // we still inform all waiting Consumers of a successful token fetch below.
  258. // This is intentional -- some consumers may need the token for cleanup
  259. // tasks. https://chromiumcodereview.appspot.com/11312124/
  260. oauth2_access_token_manager_->RegisterTokenResponse(client_id_, account_id_,
  261. scopes_, token_response_);
  262. InformWaitingRequestsAndDelete();
  263. }
  264. void OAuth2AccessTokenManager::Fetcher::OnGetTokenFailure(
  265. const GoogleServiceAuthError& error) {
  266. CHECK(fetcher_);
  267. fetcher_.reset();
  268. if (ShouldRetry(error) && RetryIfPossible(error))
  269. return;
  270. RecordOAuth2TokenFetchResult(error.state());
  271. error_ = error;
  272. InformWaitingRequestsAndDelete();
  273. }
  274. std::string OAuth2AccessTokenManager::Fetcher::GetConsumerName() const {
  275. return consumer_name_;
  276. }
  277. // Returns an exponential backoff in milliseconds including randomness less than
  278. // 1000 ms when retrying fetching an OAuth2 access token.
  279. int64_t
  280. OAuth2AccessTokenManager::Fetcher::ComputeExponentialBackOffMilliseconds(
  281. int retry_num) {
  282. DCHECK(retry_num < oauth2_access_token_manager_->max_fetch_retry_num_);
  283. int exponential_backoff_in_seconds = 1 << retry_num;
  284. // Returns a backoff with randomness < 1000ms
  285. return (exponential_backoff_in_seconds + base::RandDouble()) * 1000;
  286. }
  287. bool OAuth2AccessTokenManager::Fetcher::RetryIfPossible(
  288. const GoogleServiceAuthError& error) {
  289. if (retry_number_ < oauth2_access_token_manager_->max_fetch_retry_num_) {
  290. base::TimeDelta backoff = base::Milliseconds(
  291. ComputeExponentialBackOffMilliseconds(retry_number_));
  292. ++retry_number_;
  293. UMA_HISTOGRAM_ENUMERATION("Signin.OAuth2TokenGetRetry", error.state(),
  294. GoogleServiceAuthError::NUM_STATES);
  295. retry_timer_.Stop();
  296. retry_timer_.Start(FROM_HERE, backoff, this,
  297. &OAuth2AccessTokenManager::Fetcher::Start);
  298. return true;
  299. }
  300. return false;
  301. }
  302. bool OAuth2AccessTokenManager::Fetcher::ShouldRetry(
  303. const GoogleServiceAuthError& error) const {
  304. GoogleServiceAuthError::State error_state = error.state();
  305. bool should_retry =
  306. error_state == GoogleServiceAuthError::CONNECTION_FAILED ||
  307. error_state == GoogleServiceAuthError::REQUEST_CANCELED ||
  308. error_state == GoogleServiceAuthError::SERVICE_UNAVAILABLE;
  309. // Give the delegate a chance to correct the error first. This is a best
  310. // effort only.
  311. return should_retry || oauth2_access_token_manager_->GetDelegate()
  312. ->FixRequestErrorIfPossible();
  313. }
  314. void OAuth2AccessTokenManager::Fetcher::InformWaitingRequests() {
  315. for (const base::WeakPtr<RequestImpl>& request : waiting_requests_) {
  316. if (request)
  317. request->InformConsumer(error_, token_response_);
  318. }
  319. waiting_requests_.clear();
  320. }
  321. void OAuth2AccessTokenManager::Fetcher::InformWaitingRequestsAndDelete() {
  322. CHECK(!scheduled_for_deletion_);
  323. scheduled_for_deletion_ = true;
  324. // Deregisters itself from the manager to prevent more waiting requests to
  325. // be added when it calls back the waiting requests.
  326. oauth2_access_token_manager_->OnFetchComplete(this);
  327. InformWaitingRequests();
  328. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
  329. }
  330. void OAuth2AccessTokenManager::Fetcher::AddWaitingRequest(
  331. base::WeakPtr<RequestImpl> waiting_request) {
  332. waiting_requests_.push_back(waiting_request);
  333. }
  334. size_t OAuth2AccessTokenManager::Fetcher::GetWaitingRequestCount() const {
  335. return waiting_requests_.size();
  336. }
  337. void OAuth2AccessTokenManager::Fetcher::Cancel() {
  338. if (fetcher_)
  339. fetcher_->CancelRequest();
  340. fetcher_.reset();
  341. retry_timer_.Stop();
  342. error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
  343. InformWaitingRequestsAndDelete();
  344. }
  345. const OAuth2AccessTokenManager::ScopeSet&
  346. OAuth2AccessTokenManager::Fetcher::GetScopeSet() const {
  347. return scopes_;
  348. }
  349. const std::string& OAuth2AccessTokenManager::Fetcher::GetClientId() const {
  350. return client_id_;
  351. }
  352. const CoreAccountId& OAuth2AccessTokenManager::Fetcher::GetAccountId() const {
  353. return account_id_;
  354. }
  355. OAuth2AccessTokenManager::OAuth2AccessTokenManager(
  356. OAuth2AccessTokenManager::Delegate* delegate)
  357. : delegate_(delegate) {
  358. DCHECK(delegate_);
  359. }
  360. OAuth2AccessTokenManager::~OAuth2AccessTokenManager() {
  361. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  362. // Release all the pending fetchers.
  363. pending_fetchers_.clear();
  364. }
  365. OAuth2AccessTokenManager::Delegate* OAuth2AccessTokenManager::GetDelegate() {
  366. return delegate_;
  367. }
  368. const OAuth2AccessTokenManager::Delegate*
  369. OAuth2AccessTokenManager::GetDelegate() const {
  370. return delegate_;
  371. }
  372. void OAuth2AccessTokenManager::AddDiagnosticsObserver(
  373. DiagnosticsObserver* observer) {
  374. diagnostics_observer_list_.AddObserver(observer);
  375. }
  376. void OAuth2AccessTokenManager::RemoveDiagnosticsObserver(
  377. DiagnosticsObserver* observer) {
  378. diagnostics_observer_list_.RemoveObserver(observer);
  379. }
  380. std::unique_ptr<OAuth2AccessTokenManager::Request>
  381. OAuth2AccessTokenManager::StartRequest(const CoreAccountId& account_id,
  382. const ScopeSet& scopes,
  383. Consumer* consumer) {
  384. return StartRequestForClientWithContext(
  385. account_id, delegate_->GetURLLoaderFactory(),
  386. GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
  387. GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), scopes, consumer);
  388. }
  389. std::unique_ptr<OAuth2AccessTokenManager::Request>
  390. OAuth2AccessTokenManager::StartRequestForClient(
  391. const CoreAccountId& account_id,
  392. const std::string& client_id,
  393. const std::string& client_secret,
  394. const ScopeSet& scopes,
  395. Consumer* consumer) {
  396. return StartRequestForClientWithContext(
  397. account_id, delegate_->GetURLLoaderFactory(), client_id, client_secret,
  398. scopes, consumer);
  399. }
  400. std::unique_ptr<OAuth2AccessTokenManager::Request>
  401. OAuth2AccessTokenManager::StartRequestWithContext(
  402. const CoreAccountId& account_id,
  403. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  404. const ScopeSet& scopes,
  405. Consumer* consumer) {
  406. return StartRequestForClientWithContext(
  407. account_id, url_loader_factory,
  408. GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
  409. GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), scopes, consumer);
  410. }
  411. void OAuth2AccessTokenManager::FetchOAuth2Token(
  412. RequestImpl* request,
  413. const CoreAccountId& account_id,
  414. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  415. const std::string& client_id,
  416. const std::string& client_secret,
  417. const std::string& consumer_name,
  418. const ScopeSet& scopes) {
  419. // If there is already a pending fetcher for |scopes| and |account_id|,
  420. // simply register this |request| for those results rather than starting
  421. // a new fetcher.
  422. RequestParameters request_parameters =
  423. RequestParameters(client_id, account_id, scopes);
  424. auto iter = pending_fetchers_.find(request_parameters);
  425. if (iter != pending_fetchers_.end()) {
  426. iter->second->AddWaitingRequest(request->AsWeakPtr());
  427. return;
  428. }
  429. pending_fetchers_[request_parameters] = Fetcher::CreateAndStart(
  430. this, account_id, url_loader_factory, client_id, client_secret, scopes,
  431. consumer_name, request->AsWeakPtr());
  432. }
  433. void OAuth2AccessTokenManager::RegisterTokenResponse(
  434. const std::string& client_id,
  435. const CoreAccountId& account_id,
  436. const ScopeSet& scopes,
  437. const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  438. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  439. token_cache_[RequestParameters(client_id, account_id, scopes)] =
  440. token_response;
  441. }
  442. const OAuth2AccessTokenConsumer::TokenResponse*
  443. OAuth2AccessTokenManager::GetCachedTokenResponse(
  444. const RequestParameters& request_parameters) {
  445. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  446. TokenCache::iterator token_iterator = token_cache_.find(request_parameters);
  447. if (token_iterator == token_cache_.end())
  448. return nullptr;
  449. if (token_iterator->second.expiration_time <= base::Time::Now()) {
  450. token_cache_.erase(token_iterator);
  451. return nullptr;
  452. }
  453. return &token_iterator->second;
  454. }
  455. void OAuth2AccessTokenManager::ClearCache() {
  456. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  457. for (const auto& entry : token_cache_) {
  458. for (auto& observer : diagnostics_observer_list_)
  459. observer.OnAccessTokenRemoved(entry.first.account_id, entry.first.scopes);
  460. }
  461. token_cache_.clear();
  462. }
  463. void OAuth2AccessTokenManager::ClearCacheForAccount(
  464. const CoreAccountId& account_id) {
  465. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  466. for (TokenCache::iterator iter = token_cache_.begin();
  467. iter != token_cache_.end();
  468. /* iter incremented in body */) {
  469. if (iter->first.account_id == account_id) {
  470. for (auto& observer : diagnostics_observer_list_)
  471. observer.OnAccessTokenRemoved(account_id, iter->first.scopes);
  472. token_cache_.erase(iter++);
  473. } else {
  474. ++iter;
  475. }
  476. }
  477. }
  478. void OAuth2AccessTokenManager::CancelAllRequests() {
  479. std::vector<Fetcher*> fetchers_to_cancel;
  480. for (const auto& pending_fetcher : pending_fetchers_)
  481. fetchers_to_cancel.push_back(pending_fetcher.second.get());
  482. CancelFetchers(fetchers_to_cancel);
  483. }
  484. void OAuth2AccessTokenManager::CancelRequestsForAccount(
  485. const CoreAccountId& account_id) {
  486. std::vector<Fetcher*> fetchers_to_cancel;
  487. for (const auto& pending_fetcher : pending_fetchers_) {
  488. if (pending_fetcher.first.account_id == account_id)
  489. fetchers_to_cancel.push_back(pending_fetcher.second.get());
  490. }
  491. CancelFetchers(fetchers_to_cancel);
  492. }
  493. void OAuth2AccessTokenManager::InvalidateAccessToken(
  494. const CoreAccountId& account_id,
  495. const ScopeSet& scopes,
  496. const std::string& access_token) {
  497. InvalidateAccessTokenImpl(account_id,
  498. GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
  499. scopes, access_token);
  500. }
  501. void OAuth2AccessTokenManager::InvalidateAccessTokenImpl(
  502. const CoreAccountId& account_id,
  503. const std::string& client_id,
  504. const ScopeSet& scopes,
  505. const std::string& access_token) {
  506. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  507. RemoveCachedTokenResponse(RequestParameters(client_id, account_id, scopes),
  508. access_token);
  509. delegate_->OnAccessTokenInvalidated(account_id, client_id, scopes,
  510. access_token);
  511. }
  512. void OAuth2AccessTokenManager::
  513. set_max_authorization_token_fetch_retries_for_testing(int max_retries) {
  514. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  515. max_fetch_retry_num_ = max_retries;
  516. }
  517. size_t OAuth2AccessTokenManager::GetNumPendingRequestsForTesting(
  518. const std::string& client_id,
  519. const CoreAccountId& account_id,
  520. const ScopeSet& scopes) const {
  521. auto iter =
  522. pending_fetchers_.find(RequestParameters(client_id, account_id, scopes));
  523. return iter == pending_fetchers_.end()
  524. ? 0
  525. : iter->second->GetWaitingRequestCount();
  526. }
  527. const base::ObserverList<OAuth2AccessTokenManager::DiagnosticsObserver,
  528. true>::Unchecked&
  529. OAuth2AccessTokenManager::GetDiagnosticsObserversForTesting() {
  530. return diagnostics_observer_list_;
  531. }
  532. std::unique_ptr<OAuth2AccessTokenFetcher>
  533. OAuth2AccessTokenManager::CreateAccessTokenFetcher(
  534. const CoreAccountId& account_id,
  535. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  536. OAuth2AccessTokenConsumer* consumer) {
  537. return delegate_->CreateAccessTokenFetcher(account_id, url_loader_factory,
  538. consumer);
  539. }
  540. std::unique_ptr<OAuth2AccessTokenManager::Request>
  541. OAuth2AccessTokenManager::StartRequestForClientWithContext(
  542. const CoreAccountId& account_id,
  543. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  544. const std::string& client_id,
  545. const std::string& client_secret,
  546. const ScopeSet& scopes,
  547. Consumer* consumer) {
  548. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  549. std::unique_ptr<RequestImpl> request(new RequestImpl(account_id, consumer));
  550. for (auto& observer : diagnostics_observer_list_)
  551. observer.OnAccessTokenRequested(account_id, consumer->id(), scopes);
  552. if (!delegate_->HasRefreshToken(account_id)) {
  553. GoogleServiceAuthError error(GoogleServiceAuthError::USER_NOT_SIGNED_UP);
  554. for (auto& observer : diagnostics_observer_list_) {
  555. observer.OnFetchAccessTokenComplete(account_id, consumer->id(), scopes,
  556. error, base::Time());
  557. }
  558. base::ThreadTaskRunnerHandle::Get()->PostTask(
  559. FROM_HERE,
  560. base::BindOnce(&RequestImpl::InformConsumer, request->AsWeakPtr(),
  561. error, OAuth2AccessTokenConsumer::TokenResponse()));
  562. return std::move(request);
  563. }
  564. RequestParameters request_parameters(client_id, account_id, scopes);
  565. const OAuth2AccessTokenConsumer::TokenResponse* token_response =
  566. GetCachedTokenResponse(request_parameters);
  567. if (token_response && token_response->access_token.length()) {
  568. InformConsumerWithCachedTokenResponse(token_response, request.get(),
  569. request_parameters);
  570. } else if (delegate_->HandleAccessTokenFetch(request.get(), account_id,
  571. url_loader_factory, client_id,
  572. client_secret, scopes)) {
  573. // The delegate handling the fetch request means that we *don't* perform a
  574. // fetch.
  575. } else {
  576. // The token isn't in the cache and the delegate isn't fetching it: fetch it
  577. // ourselves!
  578. FetchOAuth2Token(request.get(), account_id, url_loader_factory, client_id,
  579. client_secret, consumer->id(), scopes);
  580. }
  581. return std::move(request);
  582. }
  583. void OAuth2AccessTokenManager::InformConsumerWithCachedTokenResponse(
  584. const OAuth2AccessTokenConsumer::TokenResponse* cache_token_response,
  585. RequestImpl* request,
  586. const RequestParameters& request_parameters) {
  587. DCHECK(cache_token_response && cache_token_response->access_token.length());
  588. for (auto& observer : diagnostics_observer_list_) {
  589. observer.OnFetchAccessTokenComplete(
  590. request_parameters.account_id, request->GetConsumerId(),
  591. request_parameters.scopes, GoogleServiceAuthError::AuthErrorNone(),
  592. cache_token_response->expiration_time);
  593. }
  594. base::ThreadTaskRunnerHandle::Get()->PostTask(
  595. FROM_HERE,
  596. base::BindOnce(&RequestImpl::InformConsumer, request->AsWeakPtr(),
  597. GoogleServiceAuthError(GoogleServiceAuthError::NONE),
  598. *cache_token_response));
  599. }
  600. bool OAuth2AccessTokenManager::RemoveCachedTokenResponse(
  601. const RequestParameters& request_parameters,
  602. const std::string& token_to_remove) {
  603. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  604. TokenCache::iterator token_iterator = token_cache_.find(request_parameters);
  605. if (token_iterator != token_cache_.end() &&
  606. token_iterator->second.access_token == token_to_remove) {
  607. for (auto& observer : diagnostics_observer_list_) {
  608. observer.OnAccessTokenRemoved(request_parameters.account_id,
  609. request_parameters.scopes);
  610. }
  611. token_cache_.erase(token_iterator);
  612. return true;
  613. }
  614. return false;
  615. }
  616. void OAuth2AccessTokenManager::OnFetchComplete(
  617. OAuth2AccessTokenManager::Fetcher* fetcher) {
  618. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  619. // Note |fetcher| is recorded in |pending_fetcher_| mapped from its
  620. // combination of client ID, account ID, and scope set. This is guaranteed as
  621. // follows; here a Fetcher is said to be uncompleted if it has not finished
  622. // calling back
  623. // OAuth2AccessTokenManager::OnFetchComplete().
  624. //
  625. // (1) All the live Fetchers are created by this manager.
  626. // This is because (1) all the live Fetchers are created by a live
  627. // manager, as all the fetchers created by a manager are destructed in the
  628. // manager's dtor.
  629. //
  630. // (2) All the uncompleted Fetchers created by this manager are recorded in
  631. // |pending_fetchers_|.
  632. // This is because (1) all the created Fetchers are added to
  633. // |pending_fetchers_| (in method StartRequest()) and (2) method
  634. // OnFetchComplete() is the only place where a Fetcher is erased from
  635. // |pending_fetchers_|. Note no Fetcher is erased in method
  636. // StartRequest().
  637. //
  638. // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped from
  639. // its combination of client ID, account ID, and scope set. This is
  640. // guaranteed by Fetcher creation in method StartRequest().
  641. //
  642. // When this method is called, |fetcher| is alive and uncompleted.
  643. // By (1), |fetcher| is created by this manager.
  644. // Then by (2), |fetcher| is recorded in |pending_fetchers_|.
  645. // Then by (3), |fetcher_| is mapped from its combination of client ID,
  646. // account ID, and scope set.
  647. RequestParameters request_param(
  648. fetcher->GetClientId(), fetcher->GetAccountId(), fetcher->GetScopeSet());
  649. auto iter = pending_fetchers_.find(request_param);
  650. DCHECK(iter != pending_fetchers_.end());
  651. DCHECK_EQ(fetcher, iter->second.get());
  652. // The Fetcher deletes itself.
  653. iter->second.release();
  654. pending_fetchers_.erase(iter);
  655. // `delegate_` might cancel all pending fetchers, so it's important to call it
  656. // only after `fetcher` was removed from the map. See
  657. // https://crbug.com/1186630.
  658. delegate_->OnAccessTokenFetched(fetcher->GetAccountId(), fetcher->error());
  659. const OAuth2AccessTokenConsumer::TokenResponse* entry =
  660. GetCachedTokenResponse(request_param);
  661. for (const base::WeakPtr<RequestImpl>& req : fetcher->waiting_requests()) {
  662. if (req) {
  663. for (auto& observer : diagnostics_observer_list_) {
  664. observer.OnFetchAccessTokenComplete(
  665. req->GetAccountId(), req->GetConsumerId(), fetcher->GetScopeSet(),
  666. fetcher->error(), entry ? entry->expiration_time : base::Time());
  667. }
  668. }
  669. }
  670. }
  671. void OAuth2AccessTokenManager::CancelFetchers(
  672. std::vector<Fetcher*> fetchers_to_cancel) {
  673. for (Fetcher* pending_fetcher : fetchers_to_cancel)
  674. pending_fetcher->Cancel();
  675. }