Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/signin/profile_oauth2_token_service.h" | 5 #include "chrome/browser/signin/profile_oauth2_token_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 } | 93 } |
| 94 | 94 |
| 95 void ProfileOAuth2TokenService::Shutdown() { | 95 void ProfileOAuth2TokenService::Shutdown() { |
| 96 CancelAllRequests(); | 96 CancelAllRequests(); |
| 97 signin_global_error_->RemoveProvider(this); | 97 signin_global_error_->RemoveProvider(this); |
| 98 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( | 98 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( |
| 99 signin_global_error_.get()); | 99 signin_global_error_.get()); |
| 100 signin_global_error_.reset(); | 100 signin_global_error_.reset(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 std::string ProfileOAuth2TokenService::GetRefreshToken() { | 103 std::string ProfileOAuth2TokenService::GetRefreshToken( |
| 104 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 104 const std::string& account_id) { |
| 105 if (!token_service || !token_service->HasOAuthLoginToken()) { | 105 return refresh_tokens_[account_id]; |
| 106 return std::string(); | |
| 107 } | |
| 108 return token_service->GetOAuth2LoginRefreshToken(); | |
| 109 } | 106 } |
| 110 | 107 |
| 111 void ProfileOAuth2TokenService::UpdateAuthError( | 108 void ProfileOAuth2TokenService::UpdateAuthError( |
| 112 const GoogleServiceAuthError& error) { | 109 const GoogleServiceAuthError& error) { |
| 113 // Do not report connection errors as these are not actually auth errors. | 110 // Do not report connection errors as these are not actually auth errors. |
| 114 // We also want to avoid masking a "real" auth error just because we | 111 // We also want to avoid masking a "real" auth error just because we |
| 115 // subsequently get a transient network error. | 112 // subsequently get a transient network error. |
| 116 if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) | 113 if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) |
| 117 return; | 114 return; |
| 118 | 115 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 141 ClearCache(); | 138 ClearCache(); |
| 142 UpdateAuthError(GoogleServiceAuthError::AuthErrorNone()); | 139 UpdateAuthError(GoogleServiceAuthError::AuthErrorNone()); |
| 143 FireRefreshTokenAvailable(GetAccountId(profile_)); | 140 FireRefreshTokenAvailable(GetAccountId(profile_)); |
| 144 } | 141 } |
| 145 break; | 142 break; |
| 146 } | 143 } |
| 147 case chrome::NOTIFICATION_TOKENS_CLEARED: { | 144 case chrome::NOTIFICATION_TOKENS_CLEARED: { |
| 148 CancelAllRequests(); | 145 CancelAllRequests(); |
| 149 ClearCache(); | 146 ClearCache(); |
| 150 UpdateAuthError(GoogleServiceAuthError::AuthErrorNone()); | 147 UpdateAuthError(GoogleServiceAuthError::AuthErrorNone()); |
| 151 FireRefreshTokensCleared(); | |
| 152 break; | 148 break; |
| 153 } | 149 } |
| 154 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: | 150 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: |
| 155 FireRefreshTokensLoaded(); | 151 FireRefreshTokensLoaded(); |
| 156 break; | 152 break; |
| 157 default: | 153 default: |
| 158 NOTREACHED() << "Invalid notification type=" << type; | 154 NOTREACHED() << "Invalid notification type=" << type; |
| 159 break; | 155 break; |
| 160 } | 156 } |
| 161 } | 157 } |
| 162 | 158 |
| 163 GoogleServiceAuthError ProfileOAuth2TokenService::GetAuthStatus() const { | 159 GoogleServiceAuthError ProfileOAuth2TokenService::GetAuthStatus() const { |
| 164 return last_auth_error_; | 160 return last_auth_error_; |
| 165 } | 161 } |
| 166 | 162 |
| 167 net::URLRequestContextGetter* ProfileOAuth2TokenService::GetRequestContext() { | 163 net::URLRequestContextGetter* ProfileOAuth2TokenService::GetRequestContext() { |
| 168 return profile_->GetRequestContext(); | 164 return profile_->GetRequestContext(); |
| 169 } | 165 } |
| 170 | 166 |
| 171 void ProfileOAuth2TokenService::RegisterCacheEntry( | 167 void ProfileOAuth2TokenService::RegisterCacheEntry( |
| 172 const std::string& refresh_token, | 168 const std::string& refresh_token, |
| 173 const ScopeSet& scopes, | 169 const ScopeSet& scopes, |
| 174 const std::string& access_token, | 170 const std::string& access_token, |
| 175 const base::Time& expiration_date) { | 171 const base::Time& expiration_date) { |
| 176 if (ShouldCacheForRefreshToken(TokenServiceFactory::GetForProfile(profile_), | 172 if (ShouldCacheForRefreshToken(refresh_token)) { |
| 177 refresh_token)) { | |
| 178 OAuth2TokenService::RegisterCacheEntry(refresh_token, | 173 OAuth2TokenService::RegisterCacheEntry(refresh_token, |
| 179 scopes, | 174 scopes, |
| 180 access_token, | 175 access_token, |
| 181 expiration_date); | 176 expiration_date); |
| 182 } | 177 } |
| 183 } | 178 } |
| 184 | 179 |
| 185 bool ProfileOAuth2TokenService::ShouldCacheForRefreshToken( | 180 bool ProfileOAuth2TokenService::ShouldCacheForRefreshToken( |
| 186 TokenService *token_service, | |
| 187 const std::string& refresh_token) { | 181 const std::string& refresh_token) { |
| 188 if (!token_service || | 182 for (std::map<std::string, std::string>::const_iterator iter = |
|
Andrew T Wilson (Slow)
2013/08/23 09:38:13
Add a comment as to what this is doing. Can users
fgorski
2013/08/23 19:13:35
Done. Added a comment and a TODO to investigate CH
| |
| 189 !token_service->HasOAuthLoginToken() || | 183 refresh_tokens_.begin(); iter != refresh_tokens_.end(); ++iter) { |
| 190 token_service->GetOAuth2LoginRefreshToken().compare(refresh_token) != 0) { | 184 if (iter->second == refresh_token) |
| 191 DLOG(INFO) << | 185 return true; |
| 192 "Received a token with a refresh token not maintained by TokenService."; | |
| 193 return false; | |
| 194 } | 186 } |
| 195 return true; | 187 |
| 188 DLOG(INFO) << | |
| 189 "Received a token with a refresh token not maintained by TokenService."; | |
| 190 return false; | |
| 191 } | |
| 192 | |
| 193 std::string ProfileOAuth2TokenService::GetPrimaryAccountId() { | |
| 194 SigninManagerBase* signin_manager = | |
| 195 SigninManagerFactory::GetForProfileIfExists(profile_); | |
| 196 return signin_manager ? signin_manager->GetAuthenticatedUsername() : | |
| 197 std::string(); | |
| 198 } | |
| 199 | |
| 200 std::vector<std::string> ProfileOAuth2TokenService::GetAccounts() { | |
| 201 std::vector<std::string> account_ids; | |
| 202 for (std::map<std::string, std::string>::const_iterator iter = | |
| 203 refresh_tokens_.begin(); iter != refresh_tokens_.end(); ++iter) { | |
| 204 account_ids.push_back(iter->first); | |
| 205 } | |
| 206 return account_ids; | |
| 196 } | 207 } |
| 197 | 208 |
| 198 void ProfileOAuth2TokenService::UpdateCredentials( | 209 void ProfileOAuth2TokenService::UpdateCredentials( |
| 199 const std::string& account_id, | 210 const std::string& account_id, |
| 200 const std::string& refresh_token) { | 211 const std::string& refresh_token) { |
| 201 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 212 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 202 DCHECK(!refresh_token.empty()); | 213 DCHECK(!refresh_token.empty()); |
| 203 | 214 |
| 204 bool refresh_token_present = refresh_tokens_.count(account_id) > 0; | 215 bool refresh_token_present = refresh_tokens_.count(account_id) > 0; |
| 205 if (!refresh_token_present || | 216 if (!refresh_token_present || |
| 206 refresh_tokens_[account_id] != refresh_token) { | 217 refresh_tokens_[account_id] != refresh_token) { |
| 207 // If token present, and different from the new one, cancel its requests. | 218 // If token present, and different from the new one, cancel its requests, |
| 208 if (refresh_token_present) | 219 // and clear the entries in cache related to that account. |
| 220 if (refresh_token_present) { | |
| 209 CancelRequestsForToken(refresh_tokens_[account_id]); | 221 CancelRequestsForToken(refresh_tokens_[account_id]); |
| 222 // ClearCacheForAccount(account_id); | |
|
Andrew T Wilson (Slow)
2013/08/23 09:38:13
Add a TODO here?
fgorski
2013/08/23 19:13:35
Done.
| |
| 223 } | |
| 210 | 224 |
| 211 // Save the token in memory and in persistent store. | 225 // Save the token in memory and in persistent store. |
| 212 refresh_tokens_[account_id] = refresh_token; | 226 refresh_tokens_[account_id] = refresh_token; |
| 213 scoped_refptr<TokenWebData> token_web_data = | 227 scoped_refptr<TokenWebData> token_web_data = |
| 214 TokenWebData::FromBrowserContext(profile_); | 228 TokenWebData::FromBrowserContext(profile_); |
| 215 if (token_web_data.get()) | 229 if (token_web_data.get()) |
| 216 token_web_data->SetTokenForService(ApplyAccountIdPrefix(account_id), | 230 token_web_data->SetTokenForService(ApplyAccountIdPrefix(account_id), |
| 217 refresh_token); | 231 refresh_token); |
| 218 | 232 |
| 233 UpdateAuthError(GoogleServiceAuthError::AuthErrorNone()); | |
|
Andrew T Wilson (Slow)
2013/08/23 09:38:13
Just a note that we probably have to figure out ho
fgorski
2013/08/23 19:13:35
Done. Included a section in design doc. Updated th
| |
| 219 FireRefreshTokenAvailable(account_id); | 234 FireRefreshTokenAvailable(account_id); |
| 220 // TODO(fgorski): Notify diagnostic observers. | 235 // TODO(fgorski): Notify diagnostic observers. |
| 221 } | 236 } |
| 222 } | 237 } |
| 223 | 238 |
| 224 void ProfileOAuth2TokenService::RevokeCredentials( | 239 void ProfileOAuth2TokenService::RevokeCredentials( |
| 225 const std::string& account_id) { | 240 const std::string& account_id) { |
| 226 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 241 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 227 | 242 |
| 228 if (refresh_tokens_.count(account_id) > 0) { | 243 if (refresh_tokens_.count(account_id) > 0) { |
| 229 CancelRequestsForToken(refresh_tokens_[account_id]); | 244 CancelRequestsForToken(refresh_tokens_[account_id]); |
| 245 // ClearCacheForAccount(account_id); | |
| 230 refresh_tokens_.erase(account_id); | 246 refresh_tokens_.erase(account_id); |
| 231 scoped_refptr<TokenWebData> token_web_data = | 247 scoped_refptr<TokenWebData> token_web_data = |
| 232 TokenWebData::FromBrowserContext(profile_); | 248 TokenWebData::FromBrowserContext(profile_); |
| 233 if (token_web_data.get()) | 249 if (token_web_data.get()) |
| 234 token_web_data->RemoveTokenForService(ApplyAccountIdPrefix(account_id)); | 250 token_web_data->RemoveTokenForService(ApplyAccountIdPrefix(account_id)); |
| 235 FireRefreshTokenRevoked(account_id); | 251 FireRefreshTokenRevoked(account_id); |
| 236 | 252 |
| 237 // TODO(fgorski): Notify diagnostic observers. | 253 // TODO(fgorski): Notify diagnostic observers. |
| 238 } | 254 } |
| 239 } | 255 } |
| 240 | 256 |
| 241 void ProfileOAuth2TokenService::RevokeAllCredentials() { | 257 void ProfileOAuth2TokenService::RevokeAllCredentials() { |
| 242 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 258 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 243 | 259 |
| 244 CancelAllRequests(); | 260 CancelAllRequests(); |
| 245 for (std::map<std::string, std::string>::const_iterator iter = | 261 for (std::map<std::string, std::string>::const_iterator iter = |
| 246 refresh_tokens_.begin(); | 262 refresh_tokens_.begin(); |
| 247 iter != refresh_tokens_.end(); | 263 iter != refresh_tokens_.end(); |
| 248 ++iter) { | 264 ++iter) { |
| 249 FireRefreshTokenRevoked(iter->first); | 265 FireRefreshTokenRevoked(iter->first); |
| 250 } | 266 } |
| 251 refresh_tokens_.clear(); | 267 refresh_tokens_.clear(); |
| 252 | 268 |
| 253 scoped_refptr<TokenWebData> token_web_data = | 269 scoped_refptr<TokenWebData> token_web_data = |
| 254 TokenWebData::FromBrowserContext(profile_); | 270 TokenWebData::FromBrowserContext(profile_); |
| 255 if (token_web_data.get()) | 271 if (token_web_data.get()) |
| 256 token_web_data->RemoveAllTokens(); | 272 token_web_data->RemoveAllTokens(); |
| 257 FireRefreshTokensCleared(); | |
| 258 | 273 |
| 259 // TODO(fgorski): Notify diagnostic observers. | 274 // TODO(fgorski): Notify diagnostic observers. |
| 260 } | 275 } |
| 261 | 276 |
| 262 void ProfileOAuth2TokenService::LoadCredentials() { | 277 void ProfileOAuth2TokenService::LoadCredentials() { |
| 263 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 278 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 264 DCHECK_EQ(0, web_data_service_request_); | 279 DCHECK_EQ(0, web_data_service_request_); |
| 265 | 280 |
| 266 CancelAllRequests(); | 281 CancelAllRequests(); |
| 267 refresh_tokens_.clear(); | 282 refresh_tokens_.clear(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 } | 330 } |
| 316 } | 331 } |
| 317 | 332 |
| 318 if (!old_login_token.empty() && | 333 if (!old_login_token.empty() && |
| 319 refresh_tokens_.count(GetAccountId(profile_)) == 0) { | 334 refresh_tokens_.count(GetAccountId(profile_)) == 0) { |
| 320 UpdateCredentials(GetAccountId(profile_), old_login_token); | 335 UpdateCredentials(GetAccountId(profile_), old_login_token); |
| 321 } | 336 } |
| 322 | 337 |
| 323 FireRefreshTokensLoaded(); | 338 FireRefreshTokensLoaded(); |
| 324 } | 339 } |
| OLD | NEW |