| 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 |