Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2362)

Unified Diff: chrome/browser/signin/oauth2_token_service.cc

Issue 11038063: Support chrome_to_mobile job receiving Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix format Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/signin/oauth2_token_service.h ('k') | chrome/browser/signin/oauth2_token_service_factory.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/signin/oauth2_token_service.cc
diff --git a/chrome/browser/signin/oauth2_token_service.cc b/chrome/browser/signin/oauth2_token_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e805291a8831d2d02c8343a5ff6228ae14d587d6
--- /dev/null
+++ b/chrome/browser/signin/oauth2_token_service.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/signin/oauth2_token_service.h"
+
+#include "base/callback.h"
+#include "base/time.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/oauth2_token_service_factory.h"
+#include "chrome/browser/signin/token_service.h"
+#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/gaia_urls.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "google_apis/gaia/oauth2_access_token_consumer.h"
+#include "google_apis/gaia/oauth2_access_token_fetcher.h"
+
+using content::BrowserThread;
+
+// Data structure used to communicate between the thread the request is made on
+// and the UI thread where the TokenService is accessible.
+struct Tokens {
+ Tokens() : error(GoogleServiceAuthError::None()) {}
+ GoogleServiceAuthError error;
+ std::string refresh_token;
+ std::string access_token;
+ base::Time expiration_date;
+};
+
+// Callback from the UI thread to the thread the request is made on.
+typedef base::Callback<void(Tokens)> RequestCallbackType;
+
+class OAuth2TokenService::RequestImpl : public CancelableRequestConsumer,
+ public OAuth2TokenService::Request,
+ public OAuth2AccessTokenConsumer {
+ public:
+ RequestImpl(Profile* profile,
+ net::URLRequestContextGetter* getter,
+ const std::set<std::string>& scopes,
+ OAuth2AccessTokenConsumer* consumer);
+
+ virtual ~RequestImpl();
+
+ // OAuth2AccessTokenConsumer implemenation;
+ virtual void OnGetTokenSuccess(const std::string& access_token,
+ const base::Time& expiration_date) OVERRIDE;
+ virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
+
+ private:
+ friend class OAuth2TokenService;
+
+ // This method is called on the UI thread so that it can access the profile
+ // services and retrieve the tokens needed to solve or execute the request.
+ static void GetTokens(CancelableRequest<RequestCallbackType>* request,
+ Profile* profile,
+ std::set<std::string> scopes);
+
+ // Register an entry in the cache of the OAuth2TokenService associated to
+ // |profile|.
+ static void RegisterCacheEntry(Profile* profile,
+ const std::set<std::string>& scopes,
+ const std::string& access_token,
+ const base::Time& expiration_date);
+
+ // Callback on the request thread with the tokens needed to do the request.
+ void FetchWithTokens(Tokens tokens);
+
+ Profile* profile_;
+ scoped_refptr<net::URLRequestContextGetter> getter_;
+ std::set<std::string> scopes_;
+ OAuth2AccessTokenConsumer* consumer_;
+ scoped_ptr<OAuth2AccessTokenFetcher> fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(RequestImpl);
+};
+
+OAuth2TokenService::OAuth2TokenService() {
+}
+
+OAuth2TokenService::~OAuth2TokenService() {
+}
+
+void OAuth2TokenService::Initialize(Profile* profile) {
+ DCHECK(profile);
+ profile_ = profile;
+ getter_ = profile->GetRequestContext();
+ content::Source<TokenService> token_service_source(
+ TokenServiceFactory::GetForProfile(profile));
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TOKENS_CLEARED,
+ token_service_source);
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TOKEN_AVAILABLE,
+ token_service_source);
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
+ token_service_source);
+}
+
+OAuth2TokenService::Request* OAuth2TokenService::StartRequest(
+ const std::vector<std::string>& scopes,
+ OAuth2AccessTokenConsumer* consumer) {
+ std::set<std::string> scopes_set(scopes.begin(), scopes.end());
+ RequestImpl* request =
+ new RequestImpl(profile_, getter_, scopes_set, consumer);
+ scoped_refptr<CancelableRequest<RequestCallbackType> > cancellable_request(
+ new CancelableRequest<RequestCallbackType>(
+ base::Bind(&RequestImpl::FetchWithTokens,
+ base::Unretained(request))));
+ AddRequest(cancellable_request, request);
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ RequestImpl::GetTokens(cancellable_request, profile_, scopes_set);
+ } else {
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&RequestImpl::GetTokens,
+ cancellable_request,
+ profile_,
+ scopes_set));
+ }
+ return request;
+}
+
+void OAuth2TokenService::ClearCache() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ tokens_cache_.clear();
+}
+
+OAuth2TokenService::CacheEntry const* OAuth2TokenService::GetCacheEntry(
+ const std::set<std::string>& scopes) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ TokensCache::iterator token_iterator = tokens_cache_.find(scopes);
+ if (token_iterator == tokens_cache_.end())
+ return NULL;
+ if (token_iterator->second.expiration_date <= base::Time::Now()) {
+ tokens_cache_.erase(token_iterator);
+ return NULL;
+ }
+ return &token_iterator->second;
+}
+
+void OAuth2TokenService::RegisterCacheEntry(
+ const std::set<std::string>& scopes,
+ const std::string& access_token,
+ const base::Time& expiration_date) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CacheEntry& token = tokens_cache_[scopes];
+ token.access_token = access_token;
+ token.expiration_date = expiration_date;
+}
+
+void OAuth2TokenService::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK(type == chrome::NOTIFICATION_TOKENS_CLEARED ||
+ type == chrome::NOTIFICATION_TOKEN_AVAILABLE ||
+ type == chrome::NOTIFICATION_TOKEN_LOADING_FINISHED);
+ if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
+ TokenService::TokenAvailableDetails* tok_details =
+ content::Details<TokenService::TokenAvailableDetails>(details).ptr();
+ if (tok_details->service() != GaiaConstants::kGaiaOAuth2LoginRefreshToken)
+ return;
+ }
+ // The GaiaConstants::kGaiaOAuth2LoginRefreshToken token is used to create
+ // OAuth2 access tokens. If this token either changes or is cleared, any
+ // available tokens must be invalidated.
+ ClearCache();
+}
+
+OAuth2TokenService::RequestImpl::RequestImpl(
+ Profile* profile,
+ net::URLRequestContextGetter* getter,
+ const std::set<std::string>& scopes,
+ OAuth2AccessTokenConsumer* consumer)
+ : profile_(profile),
+ getter_(getter),
+ scopes_(scopes),
+ consumer_(consumer) {
+}
+
+OAuth2TokenService::RequestImpl::~RequestImpl() {
+}
+
+// static
+void OAuth2TokenService::RequestImpl::GetTokens(
+ CancelableRequest<RequestCallbackType>* request,
+ Profile* profile,
+ std::set<std::string> scopes) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (request->canceled())
+ return;
+ Tokens tokens;
+ TokenService* token_service = TokenServiceFactory::GetForProfile(profile);
+ if (!token_service || !token_service->HasOAuthLoginToken()) {
+ tokens.error =
+ GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP);
+ } else {
+ OAuth2TokenService* oauth2_token_service =
+ OAuth2TokenServiceFactory::GetForProfile(profile);
+ DCHECK(oauth2_token_service);
+ CacheEntry const* cache_entry = oauth2_token_service->GetCacheEntry(scopes);
+ if (cache_entry) {
+ tokens.access_token = cache_entry->access_token;
+ tokens.expiration_date = cache_entry->expiration_date;
+ } else {
+ tokens.refresh_token = token_service->GetOAuth2LoginRefreshToken();
+ }
+ }
+ request->ForwardResult(tokens);
+}
+
+// static
+void OAuth2TokenService::RequestImpl::RegisterCacheEntry(
+ Profile* profile,
+ const std::set<std::string>& scopes,
+ const std::string& access_token,
+ const base::Time& expiration_date) {
+ OAuth2TokenService* oauth2_token_service =
+ OAuth2TokenServiceFactory::GetForProfile(profile);
+ if (!oauth2_token_service)
+ return;
+ oauth2_token_service->RegisterCacheEntry(scopes,
+ access_token,
+ expiration_date);
+}
+
+void OAuth2TokenService::RequestImpl::OnGetTokenSuccess(
+ const std::string& access_token,
+ const base::Time& expiration_date) {
+ fetcher_.reset();
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ OAuth2TokenService* oauth2_token_service =
+ OAuth2TokenServiceFactory::GetForProfile(profile_);
+ if (oauth2_token_service) {
+ oauth2_token_service->RegisterCacheEntry(scopes_,
+ access_token,
+ expiration_date);
+ }
+ } else {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&OAuth2TokenService::RequestImpl::RegisterCacheEntry,
+ base::Unretained(profile_),
+ scopes_,
+ access_token,
+ expiration_date));
+ }
+ consumer_->OnGetTokenSuccess(access_token, expiration_date);
+}
+
+void OAuth2TokenService::RequestImpl::OnGetTokenFailure(
+ const GoogleServiceAuthError& error) {
+ fetcher_.reset();
+ consumer_->OnGetTokenFailure(error);
+}
+
+void OAuth2TokenService::RequestImpl::FetchWithTokens(Tokens tokens) {
+ if (tokens.error.state() != GoogleServiceAuthError::NONE) {
+ consumer_->OnGetTokenFailure(tokens.error);
+ return;
+ }
+ if (tokens.access_token.length()) {
+ consumer_->OnGetTokenSuccess(tokens.access_token, tokens.expiration_date);
+ return;
+ }
+ DCHECK(tokens.refresh_token.length());
+ fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_));
+ fetcher_->Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
+ GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
+ tokens.refresh_token,
+ std::vector<std::string>(scopes_.begin(), scopes_.end()));
+}
« no previous file with comments | « chrome/browser/signin/oauth2_token_service.h ('k') | chrome/browser/signin/oauth2_token_service_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698