Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "blimp/client/core/session/identity_source.h" | 5 #include "blimp/client/core/session/identity_source.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | |
| 7 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "blimp/client/core/blimp_client_switches.h" | |
| 8 | 10 |
| 9 namespace blimp { | 11 namespace blimp { |
| 10 namespace client { | 12 namespace client { |
| 11 | 13 |
| 12 namespace { | 14 namespace { |
| 13 // OAuth2 token scope. | 15 // OAuth2 token scope. |
| 14 const char kOAuth2TokenScope[] = | 16 const char kOAuth2TokenScope[] = |
| 15 "https://www.googleapis.com/auth/userinfo.email"; | 17 "https://www.googleapis.com/auth/userinfo.email"; |
| 18 | |
| 19 // Max retry times when OAuth2 token request is canceled. | |
| 20 const int kTokenRequestCancelMaxRetry = 3; | |
| 16 } // namespace | 21 } // namespace |
| 17 | 22 |
| 18 IdentitySource::IdentitySource(BlimpClientContextDelegate* delegate, | 23 IdentitySource::IdentitySource(BlimpClientContextDelegate* delegate, |
| 19 const TokenCallback& callback) | 24 const TokenCallback& callback) |
| 20 : OAuth2TokenService::Consumer("blimp_client"), | 25 : OAuth2TokenService::Consumer("blimp_client"), |
| 21 token_callback_(callback), | 26 token_callback_(callback), |
| 22 is_fetching_token_(false), | 27 is_fetching_token_(false), |
| 28 retry_times_(0), | |
| 23 delegate_(delegate) { | 29 delegate_(delegate) { |
| 24 DCHECK(delegate_); | 30 DCHECK(delegate_); |
| 25 | 31 |
| 26 // Create identity provider. | 32 // Create identity provider. |
| 27 identity_provider_ = delegate_->CreateIdentityProvider(); | 33 identity_provider_ = delegate_->CreateIdentityProvider(); |
| 28 DCHECK(identity_provider_.get()); | 34 DCHECK(identity_provider_.get()); |
| 29 identity_provider_->AddObserver(this); | 35 identity_provider_->AddObserver(this); |
| 30 } | 36 } |
| 31 | 37 |
| 32 IdentitySource::~IdentitySource() { | 38 IdentitySource::~IdentitySource() { |
| 33 identity_provider_->RemoveActiveAccountRefreshTokenObserver(this); | 39 identity_provider_->RemoveActiveAccountRefreshTokenObserver(this); |
| 34 identity_provider_->RemoveObserver(this); | 40 identity_provider_->RemoveObserver(this); |
| 35 } | 41 } |
| 36 | 42 |
| 37 void IdentitySource::Connect() { | 43 void IdentitySource::Connect() { |
| 38 if (is_fetching_token_) { | 44 if (is_fetching_token_) { |
| 39 return; | 45 return; |
| 40 } | 46 } |
| 41 | 47 |
| 48 // Pass empty token to assignment source if we have command line switches. | |
| 49 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEngineIP)) { | |
| 50 if (token_callback_) { | |
| 51 token_callback_.Run(std::string()); | |
| 52 } | |
| 53 return; | |
| 54 } | |
| 55 | |
| 56 // User must sign in first to get an OAuth2 token. | |
| 42 const std::string& account_id = identity_provider_->GetActiveAccountId(); | 57 const std::string& account_id = identity_provider_->GetActiveAccountId(); |
| 43 | |
| 44 // User must sign in first. | |
| 45 if (account_id.empty()) { | 58 if (account_id.empty()) { |
| 46 delegate_->OnAuthenticationError( | 59 delegate_->OnAuthenticationError( |
| 47 BlimpClientContextDelegate::AuthError::NOT_SIGNED_IN); | 60 BlimpClientContextDelegate::AuthError::NOT_SIGNED_IN); |
| 48 return; | 61 return; |
| 49 } | 62 } |
| 50 | 63 |
| 51 account_id_ = account_id; | 64 account_id_ = account_id; |
| 52 is_fetching_token_ = true; | 65 is_fetching_token_ = true; |
| 53 FetchAuthToken(); | 66 FetchAuthToken(); |
| 54 } | 67 } |
| 55 | 68 |
| 69 // Add sign in state observer. | |
| 70 void IdentitySource::AddObserver(IdentityProvider::Observer* observer) { | |
| 71 DCHECK(identity_provider_); | |
| 72 identity_provider_->AddObserver(observer); | |
| 73 } | |
| 74 | |
| 75 // Remove sign in state observer. | |
| 76 void IdentitySource::RemoveObserver(IdentityProvider::Observer* observer) { | |
| 77 DCHECK(identity_provider_); | |
| 78 identity_provider_->RemoveObserver(observer); | |
| 79 } | |
| 80 | |
| 56 void IdentitySource::OnGetTokenSuccess( | 81 void IdentitySource::OnGetTokenSuccess( |
| 57 const OAuth2TokenService::Request* request, | 82 const OAuth2TokenService::Request* request, |
| 58 const std::string& access_token, | 83 const std::string& access_token, |
| 59 const base::Time& expiration_time) { | 84 const base::Time& expiration_time) { |
| 60 token_request_.reset(); | 85 token_request_.reset(); |
| 61 is_fetching_token_ = false; | 86 is_fetching_token_ = false; |
| 87 retry_times_ = 0; | |
| 62 | 88 |
| 63 if (token_callback_) { | 89 if (token_callback_) { |
| 64 token_callback_.Run(access_token); | 90 token_callback_.Run(access_token); |
| 65 } | 91 } |
| 66 } | 92 } |
| 67 | 93 |
| 68 // Fail to get the token after retries attempts in native layer and Java layer. | 94 // Fail to get the token after retries attempts in native layer and Java layer. |
| 69 void IdentitySource::OnGetTokenFailure( | 95 void IdentitySource::OnGetTokenFailure( |
| 70 const OAuth2TokenService::Request* request, | 96 const OAuth2TokenService::Request* request, |
| 71 const GoogleServiceAuthError& error) { | 97 const GoogleServiceAuthError& error) { |
| 72 token_request_.reset(); | 98 token_request_.reset(); |
| 99 | |
| 100 // If request was canceled, retry. Update refresh token will cause request to | |
| 101 // cancel. | |
| 102 if (error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED && | |
|
David Trainor- moved to gerrit
2016/08/29 05:12:24
Could you elaborate on when we hit this? It looks
xingliu
2016/08/30 04:47:42
Added more comments here.
The embedder(android) m
| |
| 103 retry_times_ < kTokenRequestCancelMaxRetry) { | |
| 104 retry_times_++; | |
| 105 VLOG(1) << "Retrying to get OAuth2 token due to request cancellation. " | |
| 106 "retry time = " | |
| 107 << retry_times_; | |
| 108 FetchAuthToken(); | |
| 109 return; | |
| 110 } | |
| 111 | |
| 112 // If request failure was not caused by cancellation, or reached max retry | |
| 113 // times on request cancellation, propagate the error to embedder. | |
| 73 is_fetching_token_ = false; | 114 is_fetching_token_ = false; |
| 74 | 115 retry_times_ = 0; |
| 116 VLOG(1) << "OAuth2 token error: " << error.state(); | |
| 75 DCHECK(delegate_); | 117 DCHECK(delegate_); |
| 76 delegate_->OnAuthenticationError( | 118 delegate_->OnAuthenticationError( |
| 77 BlimpClientContextDelegate::AuthError::OAUTH_TOKEN_FAIL); | 119 BlimpClientContextDelegate::AuthError::OAUTH_TOKEN_FAIL); |
| 78 } | 120 } |
| 79 | 121 |
| 80 void IdentitySource::OnRefreshTokenAvailable(const std::string& account_id) { | 122 void IdentitySource::OnRefreshTokenAvailable(const std::string& account_id) { |
| 81 if (account_id != account_id_) { | 123 if (account_id != account_id_) { |
| 82 return; | 124 return; |
| 83 } | 125 } |
| 84 | 126 |
| 85 identity_provider_->RemoveActiveAccountRefreshTokenObserver(this); | 127 identity_provider_->RemoveActiveAccountRefreshTokenObserver(this); |
| 86 FetchAuthToken(); | 128 FetchAuthToken(); |
| 87 } | 129 } |
| 88 | 130 |
| 89 void IdentitySource::FetchAuthToken() { | 131 void IdentitySource::FetchAuthToken() { |
| 90 OAuth2TokenService* token_service = identity_provider_->GetTokenService(); | 132 OAuth2TokenService* token_service = identity_provider_->GetTokenService(); |
| 91 DCHECK(token_service); | 133 DCHECK(token_service); |
| 92 | 134 |
| 93 if (token_service->RefreshTokenIsAvailable(account_id_)) { | 135 if (token_service->RefreshTokenIsAvailable(account_id_)) { |
| 94 OAuth2TokenService::ScopeSet scopes; | 136 OAuth2TokenService::ScopeSet scopes; |
| 95 scopes.insert(kOAuth2TokenScope); | 137 scopes.insert(kOAuth2TokenScope); |
| 96 token_request_ = token_service->StartRequest(account_id_, scopes, this); | 138 token_request_ = token_service->StartRequest(account_id_, scopes, this); |
| 97 } else { | 139 } else { |
| 98 identity_provider_->AddActiveAccountRefreshTokenObserver(this); | 140 identity_provider_->AddActiveAccountRefreshTokenObserver(this); |
| 99 } | 141 } |
| 100 } | 142 } |
| 101 | 143 |
| 102 } // namespace client | 144 } // namespace client |
| 103 } // namespace blimp | 145 } // namespace blimp |
| OLD | NEW |