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

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

Issue 22581003: Handling of multiple concurrent requests from different clients in OAuth2TokenService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months 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
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
index 0b6bd5dce376e5af55b6df43bd591f3e9129c0ef..44d2d870fb7342dd1e6be299edbac85ae5697ab3 100644
--- a/chrome/browser/signin/oauth2_token_service.cc
+++ b/chrome/browser/signin/oauth2_token_service.cc
@@ -22,6 +22,57 @@
int OAuth2TokenService::max_fetch_retry_num_ = 5;
+OAuth2TokenService::ClientScopeSet::ClientScopeSet(
+ const std::string& request_origin,
+ const std::string& client_id,
+ const ScopeSet& scopes)
+ : request_origin(request_origin),
+ client_id(client_id),
+ scopes(scopes) {
+}
+
+bool OAuth2TokenService::ClientScopeSet::operator<(
+ const ClientScopeSet& set) const {
fgorski 2013/08/08 17:25:33 Will this produce strict weak ordering required by
zel 2013/08/08 19:15:18 The ordering should be fixed now and covered with
+ if (request_origin < set.request_origin)
+ return true;
+
+ if (client_id < set.client_id)
+ return true;
+
+ if (scopes < set.scopes)
+ return true;
+
+ return false;
+}
+
+OAuth2TokenService::FetchParameters::FetchParameters(
+ const std::string& request_origin,
+ const std::string& client_id,
+ const std::string& refresh_token,
+ const ScopeSet& scopes)
+ : request_origin(request_origin),
+ client_id(client_id),
+ refresh_token(refresh_token),
+ scopes(scopes) {
+}
+
+bool OAuth2TokenService::FetchParameters::operator<(
+ const FetchParameters& params) const {
fgorski 2013/08/08 17:25:33 Same comment as implementation of the ClientScopeS
zel 2013/08/08 18:31:20 you are absolutely right good catch! fixing that n
zel 2013/08/08 19:15:18 Done.
+ if (request_origin < params.request_origin)
+ return true;
+
+ if (client_id < params.client_id)
+ return true;
+
+ if (refresh_token < params.refresh_token)
+ return true;
+
+ if (scopes < params.scopes)
+ return true;
+
+ return false;
+}
+
OAuth2TokenService::RequestImpl::RequestImpl(
OAuth2TokenService::Consumer* consumer)
: consumer_(consumer) {
@@ -77,8 +128,9 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
// The given |oauth2_token_service| will be informed when fetching is done.
static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service,
net::URLRequestContextGetter* getter,
- const std::string& chrome_client_id,
- const std::string& chrome_client_secret,
+ const std::string& request_origin,
+ const std::string& client_id,
+ const std::string& client_secret,
const std::string& refresh_token,
const OAuth2TokenService::ScopeSet& scopes,
base::WeakPtr<RequestImpl> waiting_request);
@@ -91,6 +143,8 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
const OAuth2TokenService::ScopeSet& GetScopeSet() const;
const std::string& GetRefreshToken() const;
+ const std::string& GetClientId() const;
+ const std::string& GetRequestOrigin() const;
// The error result from this fetcher.
const GoogleServiceAuthError& error() const { return error_; }
@@ -104,8 +158,9 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
private:
Fetcher(OAuth2TokenService* oauth2_token_service,
net::URLRequestContextGetter* getter,
- const std::string& chrome_client_id,
- const std::string& chrome_client_secret,
+ const std::string& request_origin,
+ const std::string& client_id,
+ const std::string& client_secret,
const std::string& refresh_token,
const OAuth2TokenService::ScopeSet& scopes,
base::WeakPtr<RequestImpl> waiting_request);
@@ -135,9 +190,13 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
GoogleServiceAuthError error_;
std::string access_token_;
base::Time expiration_date_;
+
+ // Token fetch request origin identifier.
+ std::string request_origin_;
+
// OAuth2 client id and secret.
- std::string chrome_client_id_;
- std::string chrome_client_secret_;
+ std::string client_id_;
+ std::string client_secret_;
DISALLOW_COPY_AND_ASSIGN(Fetcher);
};
@@ -146,16 +205,18 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart(
OAuth2TokenService* oauth2_token_service,
net::URLRequestContextGetter* getter,
- const std::string& chrome_client_id,
- const std::string& chrome_client_secret,
+ const std::string& request_origin,
+ const std::string& client_id,
+ const std::string& client_secret,
const std::string& refresh_token,
const OAuth2TokenService::ScopeSet& scopes,
base::WeakPtr<RequestImpl> waiting_request) {
OAuth2TokenService::Fetcher* fetcher = new Fetcher(
oauth2_token_service,
getter,
- chrome_client_id,
- chrome_client_secret,
+ request_origin,
+ client_id,
+ client_secret,
refresh_token,
scopes,
waiting_request);
@@ -166,8 +227,9 @@ OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart(
OAuth2TokenService::Fetcher::Fetcher(
OAuth2TokenService* oauth2_token_service,
net::URLRequestContextGetter* getter,
- const std::string& chrome_client_id,
- const std::string& chrome_client_secret,
+ const std::string& request_origin,
+ const std::string& client_id,
+ const std::string& client_secret,
const std::string& refresh_token,
const OAuth2TokenService::ScopeSet& scopes,
base::WeakPtr<RequestImpl> waiting_request)
@@ -177,8 +239,9 @@ OAuth2TokenService::Fetcher::Fetcher(
scopes_(scopes),
retry_number_(0),
error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
- chrome_client_id_(chrome_client_id),
- chrome_client_secret_(chrome_client_secret) {
+ request_origin_(request_origin),
+ client_id_(client_id),
+ client_secret_(client_secret) {
DCHECK(oauth2_token_service_);
DCHECK(getter_.get());
DCHECK(refresh_token_.length());
@@ -193,8 +256,8 @@ OAuth2TokenService::Fetcher::~Fetcher() {
void OAuth2TokenService::Fetcher::Start() {
fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get()));
- fetcher_->Start(chrome_client_id_,
- chrome_client_secret_,
+ fetcher_->Start(client_id_,
+ client_secret_,
refresh_token_,
std::vector<std::string>(scopes_.begin(), scopes_.end()));
retry_timer_.Stop();
@@ -214,7 +277,9 @@ void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
// we still inform all waiting Consumers of a successful token fetch below.
// This is intentional -- some consumers may need the token for cleanup
// tasks. https://chromiumcodereview.appspot.com/11312124/
- oauth2_token_service_->RegisterCacheEntry(refresh_token_,
+ oauth2_token_service_->RegisterCacheEntry(request_origin_,
+ client_id_,
+ refresh_token_,
scopes_,
access_token_,
expiration_date_);
@@ -299,6 +364,14 @@ const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const {
return refresh_token_;
}
+const std::string& OAuth2TokenService::Fetcher::GetClientId() const {
+ return client_id_;
+}
+
+const std::string& OAuth2TokenService::Fetcher::GetRequestOrigin() const {
+ return request_origin_;
+}
+
OAuth2TokenService::Request::Request() {
}
@@ -339,6 +412,7 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
OAuth2TokenService::Consumer* consumer) {
return StartRequestForClientWithContext(
GetRequestContext(),
+ std::string(),
GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
scopes,
@@ -347,12 +421,14 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
scoped_ptr<OAuth2TokenService::Request>
OAuth2TokenService::StartRequestForClient(
+ const std::string& request_origin,
const std::string& client_id,
const std::string& client_secret,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer) {
return StartRequestForClientWithContext(
GetRequestContext(),
+ request_origin,
client_id,
client_secret,
scopes,
@@ -366,6 +442,7 @@ OAuth2TokenService::StartRequestWithContext(
Consumer* consumer) {
return StartRequestForClientWithContext(
getter,
+ std::string(),
GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
scopes,
@@ -375,6 +452,7 @@ OAuth2TokenService::StartRequestWithContext(
scoped_ptr<OAuth2TokenService::Request>
OAuth2TokenService::StartRequestForClientWithContext(
net::URLRequestContextGetter* getter,
+ const std::string& request_origin,
const std::string& client_id,
const std::string& client_secret,
const ScopeSet& scopes,
@@ -395,13 +473,19 @@ OAuth2TokenService::StartRequestForClientWithContext(
return request.PassAs<Request>();
}
- if (HasCacheEntry(scopes))
- return StartCacheLookupRequest(scopes, consumer);
+ ClientScopeSet client_scopes(request_origin,
+ client_id,
+ scopes);
+ if (HasCacheEntry(client_scopes))
+ return StartCacheLookupRequest(client_scopes, consumer);
// If there is already a pending fetcher for |scopes| and |refresh_token|,
// simply register this |request| for those results rather than starting
// a new fetcher.
- FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes);
+ FetchParameters fetch_parameters = FetchParameters(request_origin,
+ client_id,
+ refresh_token,
+ scopes);
std::map<FetchParameters, Fetcher*>::iterator iter =
pending_fetchers_.find(fetch_parameters);
if (iter != pending_fetchers_.end()) {
@@ -412,6 +496,7 @@ OAuth2TokenService::StartRequestForClientWithContext(
pending_fetchers_[fetch_parameters] =
Fetcher::CreateAndStart(this,
getter,
+ request_origin,
client_id,
client_secret,
refresh_token,
@@ -422,10 +507,10 @@ OAuth2TokenService::StartRequestForClientWithContext(
scoped_ptr<OAuth2TokenService::Request>
OAuth2TokenService::StartCacheLookupRequest(
- const OAuth2TokenService::ScopeSet& scopes,
+ const OAuth2TokenService::ClientScopeSet& client_scopes,
OAuth2TokenService::Consumer* consumer) {
- CHECK(HasCacheEntry(scopes));
- const CacheEntry* cache_entry = GetCacheEntry(scopes);
+ CHECK(HasCacheEntry(client_scopes));
+ const CacheEntry* cache_entry = GetCacheEntry(client_scopes);
scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&RequestImpl::InformConsumer,
@@ -439,7 +524,11 @@ scoped_ptr<OAuth2TokenService::Request>
void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes,
const std::string& invalid_token) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- RemoveCacheEntry(scopes, invalid_token);
+ RemoveCacheEntry(
+ ClientScopeSet(std::string(),
+ GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
+ scopes),
+ invalid_token);
}
void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
@@ -476,23 +565,26 @@ void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
// Then by (2), |fetcher| is recorded in |pending_fetchers_|.
// Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet.
std::map<FetchParameters, Fetcher*>::iterator iter =
- pending_fetchers_.find(std::make_pair(
- fetcher->GetRefreshToken(), fetcher->GetScopeSet()));
+ pending_fetchers_.find(FetchParameters(
+ fetcher->GetRequestOrigin(),
+ fetcher->GetClientId(),
+ fetcher->GetRefreshToken(),
+ fetcher->GetScopeSet()));
DCHECK(iter != pending_fetchers_.end());
DCHECK_EQ(fetcher, iter->second);
pending_fetchers_.erase(iter);
}
bool OAuth2TokenService::HasCacheEntry(
- const OAuth2TokenService::ScopeSet& scopes) {
- const CacheEntry* cache_entry = GetCacheEntry(scopes);
+ const ClientScopeSet& client_scopes) {
+ const CacheEntry* cache_entry = GetCacheEntry(client_scopes);
return cache_entry && cache_entry->access_token.length();
}
const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry(
- const OAuth2TokenService::ScopeSet& scopes) {
+ const ClientScopeSet& client_scopes) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- TokenCache::iterator token_iterator = token_cache_.find(scopes);
+ TokenCache::iterator token_iterator = token_cache_.find(client_scopes);
if (token_iterator == token_cache_.end())
return NULL;
if (token_iterator->second.expiration_date <= base::Time::Now()) {
@@ -503,10 +595,10 @@ const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry(
}
bool OAuth2TokenService::RemoveCacheEntry(
- const OAuth2TokenService::ScopeSet& scopes,
+ const ClientScopeSet& client_scopes,
const std::string& token_to_remove) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- TokenCache::iterator token_iterator = token_cache_.find(scopes);
+ TokenCache::iterator token_iterator = token_cache_.find(client_scopes);
if (token_iterator != token_cache_.end() &&
token_iterator->second.access_token == token_to_remove) {
token_cache_.erase(token_iterator);
@@ -516,13 +608,17 @@ bool OAuth2TokenService::RemoveCacheEntry(
}
void OAuth2TokenService::RegisterCacheEntry(
+ const std::string& request_origin,
+ const std::string& client_id,
const std::string& refresh_token,
const OAuth2TokenService::ScopeSet& scopes,
const std::string& access_token,
const base::Time& expiration_date) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- CacheEntry& token = token_cache_[scopes];
+ CacheEntry& token = token_cache_[ClientScopeSet(request_origin,
+ client_id,
+ scopes)];
token.access_token = access_token;
token.expiration_date = expiration_date;
}
@@ -554,7 +650,7 @@ void OAuth2TokenService::CancelRequestsForToken(
pending_fetchers_.begin();
iter != pending_fetchers_.end();
++iter) {
- if (iter->first.first == refresh_token)
+ if (iter->first.refresh_token == refresh_token)
fetchers_to_cancel.push_back(iter->second);
}
CancelFetchers(fetchers_to_cancel);
« no previous file with comments | « chrome/browser/signin/oauth2_token_service.h ('k') | chrome/browser/signin/oauth2_token_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698