OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "remoting/base/oauth_token_getter_impl.h" | 5 #include "remoting/base/oauth_token_getter_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 bool auto_refresh) | 49 bool auto_refresh) |
50 : authorization_credentials_(std::move(authorization_credentials)), | 50 : authorization_credentials_(std::move(authorization_credentials)), |
51 gaia_oauth_client_( | 51 gaia_oauth_client_( |
52 new gaia::GaiaOAuthClient(url_request_context_getter.get())), | 52 new gaia::GaiaOAuthClient(url_request_context_getter.get())), |
53 url_request_context_getter_(url_request_context_getter) { | 53 url_request_context_getter_(url_request_context_getter) { |
54 if (auto_refresh) { | 54 if (auto_refresh) { |
55 refresh_timer_.reset(new base::OneShotTimer()); | 55 refresh_timer_.reset(new base::OneShotTimer()); |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 OAuthTokenGetterImpl::~OAuthTokenGetterImpl() {} | 59 OAuthTokenGetterImpl::~OAuthTokenGetterImpl() { |
| 60 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 61 } |
60 | 62 |
61 void OAuthTokenGetterImpl::OnGetTokensResponse(const std::string& refresh_token, | 63 void OAuthTokenGetterImpl::OnGetTokensResponse(const std::string& refresh_token, |
62 const std::string& access_token, | 64 const std::string& access_token, |
63 int expires_seconds) { | 65 int expires_seconds) { |
64 DCHECK(CalledOnValidThread()); | 66 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
65 DCHECK(intermediate_credentials_); | 67 DCHECK(intermediate_credentials_); |
66 VLOG(1) << "Received OAuth tokens."; | 68 VLOG(1) << "Received OAuth tokens."; |
67 | 69 |
68 // Update the access token and any other auto-update timers. | 70 // Update the access token and any other auto-update timers. |
69 UpdateAccessToken(access_token, expires_seconds); | 71 UpdateAccessToken(access_token, expires_seconds); |
70 | 72 |
71 // Keep the refresh token in the authorization_credentials. | 73 // Keep the refresh token in the authorization_credentials. |
72 authorization_credentials_.reset( | 74 authorization_credentials_.reset( |
73 new OAuthTokenGetter::OAuthAuthorizationCredentials( | 75 new OAuthTokenGetter::OAuthAuthorizationCredentials( |
74 std::string(), refresh_token, | 76 std::string(), refresh_token, |
75 intermediate_credentials_->is_service_account)); | 77 intermediate_credentials_->is_service_account)); |
76 | 78 |
77 // Clear out the one time use token. | 79 // Clear out the one time use token. |
78 intermediate_credentials_.reset(); | 80 intermediate_credentials_.reset(); |
79 | 81 |
80 // At this point we don't know the email address so we need to fetch it. | 82 // At this point we don't know the email address so we need to fetch it. |
81 email_discovery_ = true; | 83 email_discovery_ = true; |
82 gaia_oauth_client_->GetUserEmail(access_token, kMaxRetries, this); | 84 gaia_oauth_client_->GetUserEmail(access_token, kMaxRetries, this); |
83 } | 85 } |
84 | 86 |
85 void OAuthTokenGetterImpl::OnRefreshTokenResponse( | 87 void OAuthTokenGetterImpl::OnRefreshTokenResponse( |
86 const std::string& access_token, | 88 const std::string& access_token, |
87 int expires_seconds) { | 89 int expires_seconds) { |
88 DCHECK(CalledOnValidThread()); | 90 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
89 DCHECK(authorization_credentials_); | 91 DCHECK(authorization_credentials_); |
90 VLOG(1) << "Received OAuth token."; | 92 VLOG(1) << "Received OAuth token."; |
91 | 93 |
92 // Update the access token and any other auto-update timers. | 94 // Update the access token and any other auto-update timers. |
93 UpdateAccessToken(access_token, expires_seconds); | 95 UpdateAccessToken(access_token, expires_seconds); |
94 | 96 |
95 if (!authorization_credentials_->is_service_account && !email_verified_) { | 97 if (!authorization_credentials_->is_service_account && !email_verified_) { |
96 gaia_oauth_client_->GetUserEmail(access_token, kMaxRetries, this); | 98 gaia_oauth_client_->GetUserEmail(access_token, kMaxRetries, this); |
97 } else { | 99 } else { |
98 response_pending_ = false; | 100 response_pending_ = false; |
99 NotifyTokenCallbacks(OAuthTokenGetterImpl::SUCCESS, | 101 NotifyTokenCallbacks(OAuthTokenGetterImpl::SUCCESS, |
100 authorization_credentials_->login, | 102 authorization_credentials_->login, |
101 oauth_access_token_); | 103 oauth_access_token_); |
102 } | 104 } |
103 } | 105 } |
104 | 106 |
105 void OAuthTokenGetterImpl::OnGetUserEmailResponse( | 107 void OAuthTokenGetterImpl::OnGetUserEmailResponse( |
106 const std::string& user_email) { | 108 const std::string& user_email) { |
107 DCHECK(CalledOnValidThread()); | 109 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
108 DCHECK(authorization_credentials_); | 110 DCHECK(authorization_credentials_); |
109 VLOG(1) << "Received user info."; | 111 VLOG(1) << "Received user info."; |
110 | 112 |
111 if (email_discovery_) { | 113 if (email_discovery_) { |
112 authorization_credentials_->login = user_email; | 114 authorization_credentials_->login = user_email; |
113 email_discovery_ = false; | 115 email_discovery_ = false; |
114 NotifyUpdatedCallbacks(authorization_credentials_->login, | 116 NotifyUpdatedCallbacks(authorization_credentials_->login, |
115 authorization_credentials_->refresh_token); | 117 authorization_credentials_->refresh_token); |
116 } else if (user_email != authorization_credentials_->login) { | 118 } else if (user_email != authorization_credentials_->login) { |
117 LOG(ERROR) << "OAuth token and email address do not refer to " | 119 LOG(ERROR) << "OAuth token and email address do not refer to " |
(...skipping 23 matching lines...) Expand all Loading... |
141 refresh_timer_->Stop(); | 143 refresh_timer_->Stop(); |
142 refresh_timer_->Start(FROM_HERE, token_expiration, this, | 144 refresh_timer_->Start(FROM_HERE, token_expiration, this, |
143 &OAuthTokenGetterImpl::RefreshAccessToken); | 145 &OAuthTokenGetterImpl::RefreshAccessToken); |
144 } | 146 } |
145 } | 147 } |
146 | 148 |
147 void OAuthTokenGetterImpl::NotifyTokenCallbacks( | 149 void OAuthTokenGetterImpl::NotifyTokenCallbacks( |
148 Status status, | 150 Status status, |
149 const std::string& user_email, | 151 const std::string& user_email, |
150 const std::string& access_token) { | 152 const std::string& access_token) { |
151 DCHECK(CalledOnValidThread()); | 153 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
152 std::queue<TokenCallback> callbacks(pending_callbacks_); | 154 std::queue<TokenCallback> callbacks(pending_callbacks_); |
153 pending_callbacks_ = std::queue<TokenCallback>(); | 155 pending_callbacks_ = std::queue<TokenCallback>(); |
154 | 156 |
155 while (!callbacks.empty()) { | 157 while (!callbacks.empty()) { |
156 callbacks.front().Run(status, user_email, access_token); | 158 callbacks.front().Run(status, user_email, access_token); |
157 callbacks.pop(); | 159 callbacks.pop(); |
158 } | 160 } |
159 } | 161 } |
160 | 162 |
161 void OAuthTokenGetterImpl::NotifyUpdatedCallbacks( | 163 void OAuthTokenGetterImpl::NotifyUpdatedCallbacks( |
162 const std::string& user_email, | 164 const std::string& user_email, |
163 const std::string& refresh_token) { | 165 const std::string& refresh_token) { |
164 DCHECK(CalledOnValidThread()); | 166 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
165 if (credentials_updated_callback_) { | 167 if (credentials_updated_callback_) { |
166 credentials_updated_callback_.Run(user_email, refresh_token); | 168 credentials_updated_callback_.Run(user_email, refresh_token); |
167 } | 169 } |
168 } | 170 } |
169 | 171 |
170 void OAuthTokenGetterImpl::OnOAuthError() { | 172 void OAuthTokenGetterImpl::OnOAuthError() { |
171 DCHECK(CalledOnValidThread()); | 173 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
172 LOG(ERROR) << "OAuth: invalid credentials."; | 174 LOG(ERROR) << "OAuth: invalid credentials."; |
173 response_pending_ = false; | 175 response_pending_ = false; |
174 | 176 |
175 // Throw away invalid credentials and force a refresh. | 177 // Throw away invalid credentials and force a refresh. |
176 oauth_access_token_.clear(); | 178 oauth_access_token_.clear(); |
177 access_token_expiry_time_ = base::Time(); | 179 access_token_expiry_time_ = base::Time(); |
178 email_verified_ = false; | 180 email_verified_ = false; |
179 | 181 |
180 NotifyTokenCallbacks(OAuthTokenGetterImpl::AUTH_ERROR, std::string(), | 182 NotifyTokenCallbacks(OAuthTokenGetterImpl::AUTH_ERROR, std::string(), |
181 std::string()); | 183 std::string()); |
182 } | 184 } |
183 | 185 |
184 void OAuthTokenGetterImpl::OnNetworkError(int response_code) { | 186 void OAuthTokenGetterImpl::OnNetworkError(int response_code) { |
185 DCHECK(CalledOnValidThread()); | 187 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
186 LOG(ERROR) << "Network error when trying to update OAuth token: " | 188 LOG(ERROR) << "Network error when trying to update OAuth token: " |
187 << response_code; | 189 << response_code; |
188 response_pending_ = false; | 190 response_pending_ = false; |
189 NotifyTokenCallbacks(OAuthTokenGetterImpl::NETWORK_ERROR, std::string(), | 191 NotifyTokenCallbacks(OAuthTokenGetterImpl::NETWORK_ERROR, std::string(), |
190 std::string()); | 192 std::string()); |
191 } | 193 } |
192 | 194 |
193 void OAuthTokenGetterImpl::CallWithToken(const TokenCallback& on_access_token) { | 195 void OAuthTokenGetterImpl::CallWithToken(const TokenCallback& on_access_token) { |
194 DCHECK(CalledOnValidThread()); | 196 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
195 if (intermediate_credentials_) { | 197 if (intermediate_credentials_) { |
196 pending_callbacks_.push(on_access_token); | 198 pending_callbacks_.push(on_access_token); |
197 if (!response_pending_) { | 199 if (!response_pending_) { |
198 GetOauthTokensFromAuthCode(); | 200 GetOauthTokensFromAuthCode(); |
199 } | 201 } |
200 } else { | 202 } else { |
201 bool need_new_auth_token = | 203 bool need_new_auth_token = |
202 access_token_expiry_time_.is_null() || | 204 access_token_expiry_time_.is_null() || |
203 base::Time::Now() >= access_token_expiry_time_ || | 205 base::Time::Now() >= access_token_expiry_time_ || |
204 (!authorization_credentials_->is_service_account && !email_verified_); | 206 (!authorization_credentials_->is_service_account && !email_verified_); |
205 | 207 |
206 if (need_new_auth_token) { | 208 if (need_new_auth_token) { |
207 pending_callbacks_.push(on_access_token); | 209 pending_callbacks_.push(on_access_token); |
208 if (!response_pending_) { | 210 if (!response_pending_) { |
209 RefreshAccessToken(); | 211 RefreshAccessToken(); |
210 } | 212 } |
211 } else { | 213 } else { |
212 on_access_token.Run(SUCCESS, authorization_credentials_->login, | 214 on_access_token.Run(SUCCESS, authorization_credentials_->login, |
213 oauth_access_token_); | 215 oauth_access_token_); |
214 } | 216 } |
215 } | 217 } |
216 } | 218 } |
217 | 219 |
218 void OAuthTokenGetterImpl::InvalidateCache() { | 220 void OAuthTokenGetterImpl::InvalidateCache() { |
219 DCHECK(CalledOnValidThread()); | 221 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
220 access_token_expiry_time_ = base::Time(); | 222 access_token_expiry_time_ = base::Time(); |
221 } | 223 } |
222 | 224 |
223 void OAuthTokenGetterImpl::GetOauthTokensFromAuthCode() { | 225 void OAuthTokenGetterImpl::GetOauthTokensFromAuthCode() { |
224 DCHECK(CalledOnValidThread()); | 226 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
225 VLOG(1) << "Fetching OAuth token from Auth Code."; | 227 VLOG(1) << "Fetching OAuth token from Auth Code."; |
226 DCHECK(!response_pending_); | 228 DCHECK(!response_pending_); |
227 | 229 |
228 // Service accounts use different API keys, as they use the client app flow. | 230 // Service accounts use different API keys, as they use the client app flow. |
229 google_apis::OAuth2Client oauth2_client = | 231 google_apis::OAuth2Client oauth2_client = |
230 intermediate_credentials_->is_service_account | 232 intermediate_credentials_->is_service_account |
231 ? google_apis::CLIENT_REMOTING_HOST | 233 ? google_apis::CLIENT_REMOTING_HOST |
232 : google_apis::CLIENT_REMOTING; | 234 : google_apis::CLIENT_REMOTING; |
233 | 235 |
234 std::string redirect_uri; | 236 std::string redirect_uri; |
(...skipping 12 matching lines...) Expand all Loading... |
247 google_apis::GetOAuth2ClientSecret(oauth2_client), redirect_uri}; | 249 google_apis::GetOAuth2ClientSecret(oauth2_client), redirect_uri}; |
248 | 250 |
249 response_pending_ = true; | 251 response_pending_ = true; |
250 | 252 |
251 gaia_oauth_client_->GetTokensFromAuthCode( | 253 gaia_oauth_client_->GetTokensFromAuthCode( |
252 client_info, intermediate_credentials_->authorization_code, kMaxRetries, | 254 client_info, intermediate_credentials_->authorization_code, kMaxRetries, |
253 this); | 255 this); |
254 } | 256 } |
255 | 257 |
256 void OAuthTokenGetterImpl::RefreshAccessToken() { | 258 void OAuthTokenGetterImpl::RefreshAccessToken() { |
257 DCHECK(CalledOnValidThread()); | 259 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
258 VLOG(1) << "Refreshing OAuth Access token."; | 260 VLOG(1) << "Refreshing OAuth Access token."; |
259 DCHECK(!response_pending_); | 261 DCHECK(!response_pending_); |
260 | 262 |
261 // Service accounts use different API keys, as they use the client app flow. | 263 // Service accounts use different API keys, as they use the client app flow. |
262 google_apis::OAuth2Client oauth2_client = | 264 google_apis::OAuth2Client oauth2_client = |
263 authorization_credentials_->is_service_account | 265 authorization_credentials_->is_service_account |
264 ? google_apis::CLIENT_REMOTING_HOST | 266 ? google_apis::CLIENT_REMOTING_HOST |
265 : google_apis::CLIENT_REMOTING; | 267 : google_apis::CLIENT_REMOTING; |
266 | 268 |
267 gaia::OAuthClientInfo client_info = { | 269 gaia::OAuthClientInfo client_info = { |
268 google_apis::GetOAuth2ClientID(oauth2_client), | 270 google_apis::GetOAuth2ClientID(oauth2_client), |
269 google_apis::GetOAuth2ClientSecret(oauth2_client), | 271 google_apis::GetOAuth2ClientSecret(oauth2_client), |
270 // Redirect URL is only used when getting tokens from auth code. It | 272 // Redirect URL is only used when getting tokens from auth code. It |
271 // is not required when getting access tokens from refresh tokens. | 273 // is not required when getting access tokens from refresh tokens. |
272 ""}; | 274 ""}; |
273 | 275 |
274 response_pending_ = true; | 276 response_pending_ = true; |
275 std::vector<std::string> empty_scope_list; // Use scope from refresh token. | 277 std::vector<std::string> empty_scope_list; // Use scope from refresh token. |
276 gaia_oauth_client_->RefreshToken(client_info, | 278 gaia_oauth_client_->RefreshToken(client_info, |
277 authorization_credentials_->refresh_token, | 279 authorization_credentials_->refresh_token, |
278 empty_scope_list, kMaxRetries, this); | 280 empty_scope_list, kMaxRetries, this); |
279 } | 281 } |
280 | 282 |
281 } // namespace remoting | 283 } // namespace remoting |
OLD | NEW |