Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: components/signin/core/browser/access_token_fetcher.cc

Issue 2582573002: Signin/OAuth: Create an AccessTokenFetcher helper class (Closed)
Patch Set: ChromeOS, for realz now Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 #include "components/signin/core/browser/access_token_fetcher.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "components/signin/core/browser/signin_manager_base.h"
12 #include "google_apis/gaia/google_service_auth_error.h"
13
14 AccessTokenFetcher::AccessTokenFetcher(
15 const std::string& oauth_consumer_name,
16 SigninManagerBase* signin_manager,
17 OAuth2TokenService* token_service,
18 const OAuth2TokenService::ScopeSet& scopes,
19 const TokenCallback& callback)
20 : OAuth2TokenService::Consumer(oauth_consumer_name),
21 signin_manager_(signin_manager),
22 token_service_(token_service),
23 scopes_(scopes),
24 callback_(callback),
25 waiting_for_sign_in_(false),
26 waiting_for_refresh_token_(false),
27 access_token_retried_(false),
28 weak_ptr_factory_(this) {
29 Start();
30 }
31
32 AccessTokenFetcher::~AccessTokenFetcher() {
33 if (waiting_for_sign_in_) {
34 signin_manager_->RemoveObserver(this);
35 }
36 if (waiting_for_refresh_token_) {
37 token_service_->RemoveObserver(this);
38 }
39 }
40
41 void AccessTokenFetcher::Start() {
42 if (signin_manager_->IsAuthenticated()) {
43 // Already signed in: Make sure we have a refresh token, then get the access
44 // token.
45 WaitForRefreshToken();
msarda 2017/01/23 17:08:09 AuthInProgress is a state that I think we should i
Marc Treib 2017/01/24 10:17:33 Ah, I didn't know that! I only knew about ChromeOS
Marc Treib 2017/01/25 14:35:43 Reviving an old comment thread: Are you positive t
46 } else if (signin_manager_->AuthInProgress()) {
47 // Currently signing in: Wait for auth to finish (to get the refresh token),
48 // then get the access token.
49 DCHECK(!waiting_for_sign_in_);
50 waiting_for_sign_in_ = true;
51 signin_manager_->AddObserver(this);
52 } else {
53 // Not signed in, no access token. Make sure not to run the callback
54 // synchronously, and not to run it if we get deleted in the meantime.
55 base::ThreadTaskRunnerHandle::Get()->PostTask(
56 FROM_HERE, base::Bind(&AccessTokenFetcher::RunCallbackNotSignedIn,
57 weak_ptr_factory_.GetWeakPtr()));
58 }
59 }
60
61 void AccessTokenFetcher::RunCallbackNotSignedIn() {
62 callback_.Run(std::string());
63 }
64
65 void AccessTokenFetcher::WaitForRefreshToken() {
66 DCHECK(signin_manager_->IsAuthenticated());
67 DCHECK(!waiting_for_refresh_token_);
68
69 if (token_service_->RefreshTokenIsAvailable(
70 signin_manager_->GetAuthenticatedAccountId())) {
71 // Already have refresh token: Get the access token directly.
72 StartAccessTokenRequest();
73 } else {
74 // Signed in, but refresh token isn't there yet: Wait for the refresh
75 // token to be loaded, then get the access token.
76 waiting_for_refresh_token_ = true;
77 token_service_->AddObserver(this);
78 }
79 }
80
81 void AccessTokenFetcher::StartAccessTokenRequest() {
82 access_token_request_ = token_service_->StartRequest(
83 signin_manager_->GetAuthenticatedAccountId(), scopes_, this);
84 }
85
86 void AccessTokenFetcher::GoogleSigninSucceeded(const std::string& account_id,
87 const std::string& username,
88 const std::string& password) {
89 DCHECK(waiting_for_sign_in_);
90 waiting_for_sign_in_ = false;
91 signin_manager_->RemoveObserver(this);
92
93 DCHECK(signin_manager_->IsAuthenticated());
94
95 WaitForRefreshToken();
96 }
97
98 void AccessTokenFetcher::GoogleSigninFailed(
99 const GoogleServiceAuthError& error) {
100 DCHECK(waiting_for_sign_in_);
101 waiting_for_sign_in_ = false;
102 signin_manager_->RemoveObserver(this);
103
104 callback_.Run(std::string());
105 }
106
107 void AccessTokenFetcher::OnRefreshTokenAvailable(
108 const std::string& account_id) {
109 DCHECK(waiting_for_refresh_token_);
110 DCHECK(signin_manager_->IsAuthenticated());
111
112 // Only react on tokens for the account the user has signed in with.
113 if (account_id != signin_manager_->GetAuthenticatedAccountId()) {
114 return;
115 }
116
117 waiting_for_refresh_token_ = false;
118 token_service_->RemoveObserver(this);
119 StartAccessTokenRequest();
120 }
121
122 void AccessTokenFetcher::OnRefreshTokensLoaded() {
123 DCHECK(waiting_for_refresh_token_);
124
125 // All refresh tokens were loaded, but we didn't get one for the account we
126 // care about. We probably won't get one any time soon.
127 waiting_for_refresh_token_ = false;
128 token_service_->RemoveObserver(this);
129 callback_.Run(std::string());
130 }
131
132 void AccessTokenFetcher::OnGetTokenSuccess(
133 const OAuth2TokenService::Request* request,
134 const std::string& access_token,
135 const base::Time& expiration_time) {
136 DCHECK_EQ(request, access_token_request_.get());
137 std::unique_ptr<OAuth2TokenService::Request> request_deleter(
138 std::move(access_token_request_));
139
140 callback_.Run(access_token);
141 }
142
143 void AccessTokenFetcher::OnGetTokenFailure(
144 const OAuth2TokenService::Request* request,
145 const GoogleServiceAuthError& error) {
146 DCHECK_EQ(request, access_token_request_.get());
147 std::unique_ptr<OAuth2TokenService::Request> request_deleter(
148 std::move(access_token_request_));
149
150 if (!access_token_retried_ &&
151 error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED) {
152 // The request can get reset by loading the refresh token (happens during
153 // startup) - try one more time.
154 access_token_retried_ = true;
155 StartAccessTokenRequest();
156 return;
157 }
158
159 DLOG(WARNING) << "Unable to get token: " << error.ToString();
160 callback_.Run(std::string());
161 }
OLDNEW
« no previous file with comments | « components/signin/core/browser/access_token_fetcher.h ('k') | components/signin/core/browser/access_token_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698