Chromium Code Reviews| Index: chrome/browser/net/gaia/token_service.cc |
| diff --git a/chrome/browser/net/gaia/token_service.cc b/chrome/browser/net/gaia/token_service.cc |
| index 35ec1835a6fe60386458e0cc354ed26ffe22d4f1..1dea37075743e047e0c74dcc45c4bb986f1089ea 100644 |
| --- a/chrome/browser/net/gaia/token_service.cc |
| +++ b/chrome/browser/net/gaia/token_service.cc |
| @@ -26,8 +26,17 @@ const char* TokenService::kServices[] = { |
| GaiaConstants::kDeviceManagementService |
| }; |
| +const char* kUnusedServiceScope = "unused-service-scope"; |
| + |
| +// Unfortunately kNumOAuthServices must be defined in the .h. |
| +// For OAuth, Chrome uses the OAuth2 service scope as the service name. |
| +const char* TokenService::kOAuthServices[] = { |
| + GaiaConstants::kSyncServiceOAuth, |
| +}; |
| + |
| TokenService::TokenService() |
| - : token_loading_query_(0) { |
| + : profile_(NULL), |
| + token_loading_query_(0) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| } |
| @@ -44,6 +53,8 @@ void TokenService::Initialize(const char* const source, |
| // Already initialized. |
| return; |
| } |
| + DCHECK(!profile_); |
| + profile_ = profile; |
| getter_ = profile->GetRequestContext(); |
|
Mattias Nissler (ping if slow)
2011/08/04 13:39:57
It doesn't make much sense to keep around both the
Rick Campbell
2011/08/04 17:24:42
I might be misunderstanding here. The current dep
|
| // Since the user can create a bookmark in incognito, sync may be running. |
| // Thus we have to go for explicit access. |
| @@ -76,9 +87,12 @@ void TokenService::ResetCredentialsInMemory() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| // Terminate any running fetchers. Callbacks will not return. |
| - for (int i = 0; i < kNumServices; i++) { |
| + for (int i = 0; i < kNumServices; ++i) { |
| fetchers_[i].reset(); |
| } |
| + for (int i = 0; i < kNumOAuthServices; ++i) { |
| + oauth_fetchers_[i].reset(); |
| + } |
| // Cancel pending loads. Callbacks will not return. |
| if (token_loading_query_) { |
| @@ -88,6 +102,8 @@ void TokenService::ResetCredentialsInMemory() { |
| token_map_.clear(); |
| credentials_ = GaiaAuthConsumer::ClientLoginResult(); |
| + oauth_token_.clear(); |
| + oauth_secret_.clear(); |
| } |
| void TokenService::UpdateCredentials( |
| @@ -104,6 +120,23 @@ void TokenService::UpdateCredentials( |
| } |
| } |
| +void TokenService::UpdateOAuthCredentials( |
| + const std::string& oauth_token, |
| + const std::string& oauth_secret) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + oauth_token_ = oauth_token; |
| + oauth_secret_ = oauth_secret; |
| + |
| + SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthToken, oauth_token); |
| + SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthSecret, oauth_secret); |
| + |
| + // Cancels any currently running requests. |
| + for (int i = 0; i < kNumOAuthServices; i++) { |
| + oauth_fetchers_[i].reset( |
| + new GaiaOAuthFetcher(this, getter_, profile_, kUnusedServiceScope)); |
| + } |
| +} |
| + |
| void TokenService::LoadTokensFromDB() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| if (web_data_service_.get()) |
| @@ -127,6 +160,10 @@ bool TokenService::AreCredentialsValid() const { |
| return !credentials_.lsid.empty() && !credentials_.sid.empty(); |
| } |
| +bool TokenService::AreOAuthCredentialsValid() const { |
| + return !oauth_token_.empty() && !oauth_secret_.empty(); |
| +} |
| + |
| bool TokenService::HasLsid() const { |
| return !credentials_.lsid.empty(); |
| } |
| @@ -145,6 +182,17 @@ void TokenService::StartFetchingTokens() { |
| } |
| } |
| +void TokenService::StartFetchingOAuthTokens() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(AreOAuthCredentialsValid()); |
| + for (int i = 0; i < kNumOAuthServices; i++) { |
| + oauth_fetchers_[i]->StartOAuthWrapBridge(oauth_token_, |
| + oauth_secret_, |
| + GaiaConstants::kGaiaOAuthDuration, |
| + kOAuthServices[i]); |
| + } |
| +} |
| + |
| // Services dependent on a token will check if a token is available. |
| // If it isn't, they'll go to sleep until they get a token event. |
| bool TokenService::HasTokenForService(const char* const service) const { |
| @@ -210,6 +258,39 @@ void TokenService::OnIssueAuthTokenFailure(const std::string& service, |
| FireTokenRequestFailedNotification(service, error); |
| } |
| +void TokenService::OnOAuthGetAccessTokenSuccess(const std::string& token, |
| + const std::string& secret) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + VLOG(1) << "TokenService::OnOAuthGetAccessTokenSuccess"; |
| + SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthToken, token); |
| + SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthSecret, secret); |
| + UpdateOAuthCredentials(token, secret); |
| +} |
| + |
| +void TokenService::OnOAuthGetAccessTokenFailure( |
| + const GoogleServiceAuthError& error) { |
| + VLOG(1) << "TokenService::OnOAuthGetAccessTokenFailure"; |
| +} |
| + |
| +void TokenService::OnOAuthWrapBridgeSuccess(const std::string& service_scope, |
| + const std::string& token, |
| + const std::string& expires_in) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + VLOG(1) << "Got an access token for " << service_scope; |
| + token_map_[service_scope] = token; |
| + FireTokenAvailableNotification(service_scope, token); |
| + SaveAuthTokenToDB(service_scope, token); |
| +} |
| + |
| +void TokenService::OnOAuthWrapBridgeFailure( |
| + const std::string& service_scope, |
| + const GoogleServiceAuthError& error) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + LOG(WARNING) << "Auth token issuing failed for service:" << service_scope; |
| + FireTokenRequestFailedNotification(service_scope, error); |
| + |
|
Mattias Nissler (ping if slow)
2011/08/04 13:39:57
remove blank line
Rick Campbell
2011/08/04 17:24:42
Done.
|
| +} |
| + |
| void TokenService::OnWebDataServiceRequestDone(WebDataService::Handle h, |
| const WDTypedResult* result) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| @@ -277,6 +358,45 @@ void TokenService::LoadTokensIntoMemory( |
| std::string())); |
| } |
| } |
| + |
| + for (int i = 0; i < kNumOAuthServices; i++) { |
| + // OnIssueAuthTokenSuccess should come from the same thread. |
| + // If a token is already present in the map, it could only have |
| + // come from a DB read or from IssueAuthToken. Since we should never |
| + // fetch from the DB twice in a browser session, it must be from |
| + // OnIssueAuthTokenSuccess, which is a live fetcher. |
| + // |
| + // Network fetched tokens take priority over DB tokens, so exclude tokens |
| + // which have already been loaded by the fetcher. |
| + if (!in_memory_tokens->count(kOAuthServices[i]) && |
| + db_tokens.count(kOAuthServices[i])) { |
| + std::string db_token = db_tokens.find(kOAuthServices[i])->second; |
| + if (!db_token.empty()) { |
| + VLOG(1) << "Loading " << kOAuthServices[i] << "token from DB: " |
| + << db_token; |
| + (*in_memory_tokens)[kOAuthServices[i]] = db_token; |
| + FireTokenAvailableNotification(kOAuthServices[i], db_token); |
| + // Failures are only for network errors. |
| + } |
| + } |
| + } |
| + |
| + if (oauth_token_.empty() && oauth_secret_.empty()) { |
| + // Look for GAIA OAuth1 access token and secret. If we have both, and the |
| + // current crendentials are empty, update the credentials. |
| + std::string oauth_token; |
| + std::string oauth_secret; |
| + |
| + if (db_tokens.count(GaiaConstants::kGaiaOAuthToken) > 0) |
| + oauth_token = db_tokens.find(GaiaConstants::kGaiaOAuthToken)->second; |
| + |
| + if (db_tokens.count(GaiaConstants::kGaiaOAuthSecret) > 0) |
| + oauth_secret = db_tokens.find(GaiaConstants::kGaiaOAuthSecret)->second; |
| + |
| + if (!oauth_token.empty() && !oauth_secret.empty()) { |
| + UpdateOAuthCredentials(oauth_token, oauth_secret); |
| + } |
| + } |
| } |
| void TokenService::Observe(int type, |