Commit 40b389af authored by bauerb@chromium.org's avatar bauerb@chromium.org

Add ManagedUserTokenFetcher to fetch scoped-down tokens.

TBR=rogerta@chromium.org
BUG=228833

Review URL: https://chromiumcodereview.appspot.com/15977002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203015 0039d316-1c4b-4281-b951-d872f2087c98
parent ca5839dc
...@@ -324,10 +324,7 @@ class DeviceCloudPolicyManagerChromeOSEnrollmentTest ...@@ -324,10 +324,7 @@ class DeviceCloudPolicyManagerChromeOSEnrollmentTest
if (robot_auth_fetch_status_ == DM_STATUS_SUCCESS) { if (robot_auth_fetch_status_ == DM_STATUS_SUCCESS) {
net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0); net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0);
ASSERT_TRUE(url_fetcher); ASSERT_TRUE(url_fetcher);
// The logic in GaiaOAuthClient seems broken, it always retries 1x on url_fetcher->SetMaxRetriesOn5xx(0);
// non-200 response codes, even if the retries are set to 0. Seems like
// its num_retries_ > source->GetMaxRetriesOn5xx() should have a >=?
url_fetcher->SetMaxRetriesOn5xx(-2);
url_fetcher->set_status(net::URLRequestStatus()); url_fetcher->set_status(net::URLRequestStatus());
url_fetcher->set_response_code(url_fetcher_response_code_); url_fetcher->set_response_code(url_fetcher_response_code_);
url_fetcher->SetResponseString(url_fetcher_response_string_); url_fetcher->SetResponseString(url_fetcher_response_string_);
......
// Copyright 2013 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.
#ifndef CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_REFRESH_TOKEN_FETCHER_H_
#define CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_REFRESH_TOKEN_FETCHER_H_
#include <string>
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
class GoogleServiceAuthError;
class OAuth2TokenService;
namespace net {
class URLRequestContextGetter;
}
// This class fetches an OAuth2 refresh token that is tied to a managed user ID
// and downscoped to a special scope for Chrome Sync for managed users.
// Fetching the token consists of the following steps:
// 1. Get an access token for the custodian from OAuth2TokenService
// (either cached or fetched).
// 2. Call the IssueToken API to mint a scoped authorization code for a
// refresh token for the managed user from the custodian's access token.
// 3. Exchange the authorization code for a refresh token for the managed
// user and return it to the caller. The refresh token can only be used to
// mint tokens with the special managed user Sync scope.
class ManagedUserRefreshTokenFetcher {
public:
typedef base::Callback<void(const GoogleServiceAuthError& /* error */,
const std::string& /* refresh_token */)>
TokenCallback;
static scoped_ptr<ManagedUserRefreshTokenFetcher> Create(
OAuth2TokenService* oauth2_token_service,
net::URLRequestContextGetter* context);
virtual ~ManagedUserRefreshTokenFetcher();
virtual void Start(const std::string& managed_user_id,
const string16& name,
const std::string& device_name,
const TokenCallback& callback) = 0;
};
#endif // CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_REFRESH_TOKEN_FETCHER_H_
...@@ -9,11 +9,14 @@ ...@@ -9,11 +9,14 @@
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
#include "chrome/browser/managed_mode/managed_user_service.h" #include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_service_factory.h" #include "chrome/browser/managed_mode/managed_user_service_factory.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/sync/glue/device_info.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h" #include "components/user_prefs/pref_registry_syncable.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/google_service_auth_error.h"
#include "sync/api/sync_change.h" #include "sync/api/sync_change.h"
#include "sync/api/sync_error_factory.h" #include "sync/api/sync_error_factory.h"
...@@ -52,9 +55,11 @@ SyncData CreateLocalSyncData(const std::string& id, ...@@ -52,9 +55,11 @@ SyncData CreateLocalSyncData(const std::string& id,
} // namespace } // namespace
ManagedUserRegistrationService::ManagedUserRegistrationService( ManagedUserRegistrationService::ManagedUserRegistrationService(
PrefService* prefs) PrefService* prefs,
scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher)
: weak_ptr_factory_(this), : weak_ptr_factory_(this),
prefs_(prefs), prefs_(prefs),
token_fetcher_(token_fetcher.Pass()),
pending_managed_user_acknowledged_(false) { pending_managed_user_acknowledged_(false) {
pref_change_registrar_.Init(prefs); pref_change_registrar_.Init(prefs);
pref_change_registrar_.Add( pref_change_registrar_.Add(
...@@ -103,7 +108,9 @@ void ManagedUserRegistrationService::Register( ...@@ -103,7 +108,9 @@ void ManagedUserRegistrationService::Register(
} }
callback_ = callback; callback_ = callback;
OnReceivedToken("abcdef"); // TODO(bauerb): This is a stub implementation. browser_sync::DeviceInfo::CreateLocalDeviceInfo(
base::Bind(&ManagedUserRegistrationService::FetchToken,
weak_ptr_factory_.GetWeakPtr(), name));
} }
ProfileManager::CreateCallback ProfileManager::CreateCallback
...@@ -268,8 +275,24 @@ void ManagedUserRegistrationService::OnManagedUserAcknowledged( ...@@ -268,8 +275,24 @@ void ManagedUserRegistrationService::OnManagedUserAcknowledged(
DispatchCallbackIfReady(); DispatchCallbackIfReady();
} }
void ManagedUserRegistrationService::OnReceivedToken(const std::string& token) { void ManagedUserRegistrationService::FetchToken(
DCHECK(pending_managed_user_token_.empty()); const string16& name,
const browser_sync::DeviceInfo& device_info) {
token_fetcher_->Start(
pending_managed_user_id_, name, device_info.client_name(),
base::Bind(&ManagedUserRegistrationService::OnReceivedToken,
weak_ptr_factory_.GetWeakPtr()));
}
void ManagedUserRegistrationService::OnReceivedToken(
const GoogleServiceAuthError& error,
const std::string& token) {
if (error.state() != GoogleServiceAuthError::NONE) {
DispatchCallback(error);
return;
}
DCHECK(!token.empty());
pending_managed_user_token_ = token; pending_managed_user_token_ = token;
DispatchCallbackIfReady(); DispatchCallbackIfReady();
} }
......
...@@ -17,8 +17,13 @@ ...@@ -17,8 +17,13 @@
#include "sync/api/syncable_service.h" #include "sync/api/syncable_service.h"
class GoogleServiceAuthError; class GoogleServiceAuthError;
class ManagedUserRefreshTokenFetcher;
class PrefService; class PrefService;
namespace browser_sync {
class DeviceInfo;
}
namespace user_prefs { namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} }
...@@ -37,13 +42,17 @@ class ManagedUserRegistrationService : public BrowserContextKeyedService, ...@@ -37,13 +42,17 @@ class ManagedUserRegistrationService : public BrowserContextKeyedService,
const std::string& /* token */)> const std::string& /* token */)>
RegistrationCallback; RegistrationCallback;
explicit ManagedUserRegistrationService(PrefService* prefs); ManagedUserRegistrationService(
PrefService* prefs,
scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher);
virtual ~ManagedUserRegistrationService(); virtual ~ManagedUserRegistrationService();
static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
// Registers a new managed user with the server. |name| is the display name of // Registers a new managed user with the server. |name| is the display name of
// the user. |callback| is called with the result of the registration. // the user. |callback| is called with the result of the registration.
// TODO(bauerb): There should be a way to cancel a pending managed user
// registration.
void Register(const string16& name, const RegistrationCallback& callback); void Register(const string16& name, const RegistrationCallback& callback);
// Convenience method that registers a new managed user with the server and // Convenience method that registers a new managed user with the server and
...@@ -77,8 +86,13 @@ class ManagedUserRegistrationService : public BrowserContextKeyedService, ...@@ -77,8 +86,13 @@ class ManagedUserRegistrationService : public BrowserContextKeyedService,
// Called when the Sync server has acknowledged a newly created managed user. // Called when the Sync server has acknowledged a newly created managed user.
void OnManagedUserAcknowledged(const std::string& managed_user_id); void OnManagedUserAcknowledged(const std::string& managed_user_id);
// Fetches the managed user token when we have the device info.
void FetchToken(const string16& name,
const browser_sync::DeviceInfo& device_info);
// Called when we have received a token for the managed user. // Called when we have received a token for the managed user.
void OnReceivedToken(const std::string& token); void OnReceivedToken(const GoogleServiceAuthError& error,
const std::string& token);
// Dispatches the callback if all the conditions have been met. // Dispatches the callback if all the conditions have been met.
void DispatchCallbackIfReady(); void DispatchCallbackIfReady();
...@@ -94,6 +108,7 @@ class ManagedUserRegistrationService : public BrowserContextKeyedService, ...@@ -94,6 +108,7 @@ class ManagedUserRegistrationService : public BrowserContextKeyedService,
base::WeakPtrFactory<ManagedUserRegistrationService> weak_ptr_factory_; base::WeakPtrFactory<ManagedUserRegistrationService> weak_ptr_factory_;
PrefService* prefs_; PrefService* prefs_;
PrefChangeRegistrar pref_change_registrar_; PrefChangeRegistrar pref_change_registrar_;
scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
scoped_ptr<syncer::SyncChangeProcessor> sync_processor_; scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
scoped_ptr<syncer::SyncErrorFactory> error_handler_; scoped_ptr<syncer::SyncErrorFactory> error_handler_;
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
#include "chrome/browser/managed_mode/managed_user_registration_service_factory.h" #include "chrome/browser/managed_mode/managed_user_registration_service_factory.h"
#include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
#include "chrome/browser/managed_mode/managed_user_registration_service.h" #include "chrome/browser/managed_mode/managed_user_registration_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h" #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
// static // static
...@@ -23,13 +27,20 @@ ManagedUserRegistrationServiceFactory::GetInstance() { ...@@ -23,13 +27,20 @@ ManagedUserRegistrationServiceFactory::GetInstance() {
// static // static
BrowserContextKeyedService* BrowserContextKeyedService*
ManagedUserRegistrationServiceFactory::BuildInstanceFor(Profile* profile) { ManagedUserRegistrationServiceFactory::BuildInstanceFor(Profile* profile) {
return new ManagedUserRegistrationService(profile->GetPrefs()); OAuth2TokenService* oauth2_token_service =
ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
return new ManagedUserRegistrationService(
profile->GetPrefs(),
ManagedUserRefreshTokenFetcher::Create(oauth2_token_service,
profile->GetRequestContext()));
} }
ManagedUserRegistrationServiceFactory::ManagedUserRegistrationServiceFactory() ManagedUserRegistrationServiceFactory::ManagedUserRegistrationServiceFactory()
: BrowserContextKeyedServiceFactory( : BrowserContextKeyedServiceFactory(
"ManagedUserRegistrationService", "ManagedUserRegistrationService",
BrowserContextDependencyManager::GetInstance()) {} BrowserContextDependencyManager::GetInstance()) {
DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
}
ManagedUserRegistrationServiceFactory:: ManagedUserRegistrationServiceFactory::
~ManagedUserRegistrationServiceFactory() {} ~ManagedUserRegistrationServiceFactory() {}
......
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
#include <string> #include <string>
#include "base/bind.h" #include "base/bind.h"
#include "base/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
#include "chrome/browser/managed_mode/managed_user_registration_service.h" #include "chrome/browser/managed_mode/managed_user_registration_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
...@@ -29,6 +32,8 @@ using syncer::SyncMergeResult; ...@@ -29,6 +32,8 @@ using syncer::SyncMergeResult;
namespace { namespace {
const char kManagedUserToken[] = "managedusertoken";
class MockChangeProcessor : public SyncChangeProcessor { class MockChangeProcessor : public SyncChangeProcessor {
public: public:
MockChangeProcessor() {} MockChangeProcessor() {}
...@@ -62,6 +67,22 @@ SyncChange MockChangeProcessor::GetChange(const std::string& id) const { ...@@ -62,6 +67,22 @@ SyncChange MockChangeProcessor::GetChange(const std::string& id) const {
return SyncChange(); return SyncChange();
} }
class MockManagedUserRefreshTokenFetcher
: public ManagedUserRefreshTokenFetcher {
public:
MockManagedUserRefreshTokenFetcher() {}
virtual ~MockManagedUserRefreshTokenFetcher() {}
// ManagedUserRefreshTokenFetcher implementation:
virtual void Start(const std::string& managed_user_id,
const string16& name,
const std::string& device_name,
const TokenCallback& callback) OVERRIDE {
GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
callback.Run(error, kManagedUserToken);
}
};
} // namespace } // namespace
class ManagedUserRegistrationServiceTest : public ::testing::Test { class ManagedUserRegistrationServiceTest : public ::testing::Test {
...@@ -94,6 +115,8 @@ class ManagedUserRegistrationServiceTest : public ::testing::Test { ...@@ -94,6 +115,8 @@ class ManagedUserRegistrationServiceTest : public ::testing::Test {
void OnManagedUserRegistered(const GoogleServiceAuthError& error, void OnManagedUserRegistered(const GoogleServiceAuthError& error,
const std::string& token); const std::string& token);
base::MessageLoop message_loop_;
base::RunLoop run_loop_;
base::WeakPtrFactory<ManagedUserRegistrationServiceTest> weak_ptr_factory_; base::WeakPtrFactory<ManagedUserRegistrationServiceTest> weak_ptr_factory_;
TestingPrefServiceSyncable prefs_; TestingPrefServiceSyncable prefs_;
scoped_ptr<ManagedUserRegistrationService> service_; scoped_ptr<ManagedUserRegistrationService> service_;
...@@ -114,12 +137,15 @@ class ManagedUserRegistrationServiceTest : public ::testing::Test { ...@@ -114,12 +137,15 @@ class ManagedUserRegistrationServiceTest : public ::testing::Test {
ManagedUserRegistrationServiceTest::ManagedUserRegistrationServiceTest() ManagedUserRegistrationServiceTest::ManagedUserRegistrationServiceTest()
: weak_ptr_factory_(this), : weak_ptr_factory_(this),
service_(new ManagedUserRegistrationService(&prefs_)),
change_processor_(NULL), change_processor_(NULL),
sync_data_id_(0), sync_data_id_(0),
received_callback_(false), received_callback_(false),
error_(GoogleServiceAuthError::NUM_STATES) { error_(GoogleServiceAuthError::NUM_STATES) {
ManagedUserRegistrationService::RegisterUserPrefs(prefs_.registry()); ManagedUserRegistrationService::RegisterUserPrefs(prefs_.registry());
scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher(
new MockManagedUserRefreshTokenFetcher);
service_.reset(
new ManagedUserRegistrationService(&prefs_, token_fetcher.Pass()));
} }
ManagedUserRegistrationServiceTest::~ManagedUserRegistrationServiceTest() { ManagedUserRegistrationServiceTest::~ManagedUserRegistrationServiceTest() {
...@@ -180,6 +206,8 @@ void ManagedUserRegistrationServiceTest::Acknowledge() { ...@@ -180,6 +206,8 @@ void ManagedUserRegistrationServiceTest::Acknowledge() {
SyncData::CreateRemoteData(++sync_data_id_, specifics))); SyncData::CreateRemoteData(++sync_data_id_, specifics)));
} }
service()->ProcessSyncChanges(FROM_HERE, new_changes); service()->ProcessSyncChanges(FROM_HERE, new_changes);
run_loop_.Run();
} }
void ManagedUserRegistrationServiceTest::ResetService() { void ManagedUserRegistrationServiceTest::ResetService() {
...@@ -194,6 +222,7 @@ void ManagedUserRegistrationServiceTest::OnManagedUserRegistered( ...@@ -194,6 +222,7 @@ void ManagedUserRegistrationServiceTest::OnManagedUserRegistered(
received_callback_ = true; received_callback_ = true;
error_ = error; error_ = error;
token_ = token; token_ = token;
run_loop_.Quit();
} }
TEST_F(ManagedUserRegistrationServiceTest, MergeEmpty) { TEST_F(ManagedUserRegistrationServiceTest, MergeEmpty) {
......
...@@ -33,7 +33,7 @@ scoped_ptr<OAuth2TokenService::Request> ...@@ -33,7 +33,7 @@ scoped_ptr<OAuth2TokenService::Request>
ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid(); ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid();
sync_service->FetchOAuth2Token( sync_service->FetchOAuth2Token(
scope_list.front(), scope_list.front(),
base::Bind(&OAuth2TokenService::InformConsumer, base::Bind(&RequestImpl::InformConsumer,
request->AsWeakPtr())); request->AsWeakPtr()));
return request.PassAs<Request>(); return request.PassAs<Request>();
} }
......
...@@ -303,18 +303,6 @@ bool OAuth2TokenService::RefreshTokenIsAvailable() { ...@@ -303,18 +303,6 @@ bool OAuth2TokenService::RefreshTokenIsAvailable() {
return !GetRefreshToken().empty(); return !GetRefreshToken().empty();
} }
// static
void OAuth2TokenService::InformConsumer(
base::WeakPtr<OAuth2TokenService::RequestImpl> request,
const GoogleServiceAuthError& error,
const std::string& access_token,
const base::Time& expiration_date) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (request)
request->InformConsumer(error, access_token, expiration_date);
}
scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
const OAuth2TokenService::ScopeSet& scopes, const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer) { OAuth2TokenService::Consumer* consumer) {
...@@ -325,7 +313,7 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( ...@@ -325,7 +313,7 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
std::string refresh_token = GetRefreshToken(); std::string refresh_token = GetRefreshToken();
if (refresh_token.empty()) { if (refresh_token.empty()) {
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&OAuth2TokenService::InformConsumer, &RequestImpl::InformConsumer,
request->AsWeakPtr(), request->AsWeakPtr(),
GoogleServiceAuthError( GoogleServiceAuthError(
GoogleServiceAuthError::USER_NOT_SIGNED_UP), GoogleServiceAuthError::USER_NOT_SIGNED_UP),
...@@ -361,7 +349,7 @@ scoped_ptr<OAuth2TokenService::Request> ...@@ -361,7 +349,7 @@ scoped_ptr<OAuth2TokenService::Request>
const CacheEntry* cache_entry = GetCacheEntry(scopes); const CacheEntry* cache_entry = GetCacheEntry(scopes);
scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&OAuth2TokenService::InformConsumer, &RequestImpl::InformConsumer,
request->AsWeakPtr(), request->AsWeakPtr(),
GoogleServiceAuthError(GoogleServiceAuthError::NONE), GoogleServiceAuthError(GoogleServiceAuthError::NONE),
cache_entry->access_token, cache_entry->access_token,
...@@ -440,7 +428,7 @@ bool OAuth2TokenService::RemoveCacheEntry( ...@@ -440,7 +428,7 @@ bool OAuth2TokenService::RemoveCacheEntry(
const std::string& token_to_remove) { const std::string& token_to_remove) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
TokenCache::iterator token_iterator = token_cache_.find(scopes); TokenCache::iterator token_iterator = token_cache_.find(scopes);
if (token_iterator == token_cache_.end() && if (token_iterator != token_cache_.end() &&
token_iterator->second.access_token == token_to_remove) { token_iterator->second.access_token == token_to_remove) {
token_cache_.erase(token_iterator); token_cache_.erase(token_iterator);
return true; return true;
......
...@@ -148,12 +148,6 @@ class OAuth2TokenService { ...@@ -148,12 +148,6 @@ class OAuth2TokenService {
Consumer* const consumer_; Consumer* const consumer_;
}; };
// Informs the consumer of |request| fetch results.
static void InformConsumer(base::WeakPtr<RequestImpl> request,
const GoogleServiceAuthError& error,
const std::string& access_token,
const base::Time& expiration_date);
private: private:
// Class that fetches an OAuth2 access token for a given set of scopes and // Class that fetches an OAuth2 access token for a given set of scopes and
// OAuth2 refresh token. // OAuth2 refresh token.
......
...@@ -404,7 +404,7 @@ TEST_F(OAuth2TokenServiceTest, RetryingConsumer) { ...@@ -404,7 +404,7 @@ TEST_F(OAuth2TokenServiceTest, RetryingConsumer) {
EXPECT_EQ(0, consumer.number_of_errors_); EXPECT_EQ(0, consumer.number_of_errors_);
net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
EXPECT_TRUE(fetcher); ASSERT_TRUE(fetcher);
fetcher->set_response_code(net::HTTP_UNAUTHORIZED); fetcher->set_response_code(net::HTTP_UNAUTHORIZED);
fetcher->SetResponseString(std::string()); fetcher->SetResponseString(std::string());
fetcher->delegate()->OnURLFetchComplete(fetcher); fetcher->delegate()->OnURLFetchComplete(fetcher);
...@@ -412,10 +412,59 @@ TEST_F(OAuth2TokenServiceTest, RetryingConsumer) { ...@@ -412,10 +412,59 @@ TEST_F(OAuth2TokenServiceTest, RetryingConsumer) {
EXPECT_EQ(1, consumer.number_of_errors_); EXPECT_EQ(1, consumer.number_of_errors_);
fetcher = factory_.GetFetcherByID(0); fetcher = factory_.GetFetcherByID(0);
EXPECT_TRUE(fetcher); ASSERT_TRUE(fetcher);
fetcher->set_response_code(net::HTTP_UNAUTHORIZED); fetcher->set_response_code(net::HTTP_UNAUTHORIZED);
fetcher->SetResponseString(std::string()); fetcher->SetResponseString(std::string());
fetcher->delegate()->OnURLFetchComplete(fetcher); fetcher->delegate()->OnURLFetchComplete(fetcher);
EXPECT_EQ(0, consumer.number_of_successful_tokens_); EXPECT_EQ(0, consumer.number_of_successful_tokens_);
EXPECT_EQ(2, consumer.number_of_errors_); EXPECT_EQ(2, consumer.number_of_errors_);
} }
TEST_F(OAuth2TokenServiceTest, InvalidateToken) {
std::set<std::string> scopes;
oauth2_service_->set_refresh_token("refreshToken");
// First request.
scoped_ptr<OAuth2TokenService::Request> request(
oauth2_service_->StartRequest(scopes, &consumer_));
message_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
EXPECT_TRUE(fetcher);
fetcher->set_response_code(net::HTTP_OK);
fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
fetcher->delegate()->OnURLFetchComplete(fetcher);
EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
EXPECT_EQ("token", consumer_.last_token_);
// Second request, should return the same token without needing a network
// request.
scoped_ptr<OAuth2TokenService::Request> request2(
oauth2_service_->StartRequest(scopes, &consumer_));
message_loop_.RunUntilIdle();
// No new network fetcher.
EXPECT_EQ(fetcher, factory_.GetFetcherByID(0));
EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
EXPECT_EQ("token", consumer_.last_token_);
// Invalidating the token should return a new token on the next request.
oauth2_service_->InvalidateToken(scopes, consumer_.last_token_);
scoped_ptr<OAuth2TokenService::Request> request3(
oauth2_service_->StartRequest(scopes, &consumer_));
message_loop_.RunUntilIdle();
EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
fetcher = factory_.GetFetcherByID(0);
EXPECT_TRUE(fetcher);
fetcher->set_response_code(net::HTTP_OK);
fetcher->SetResponseString(GetValidTokenResponse("token2", 3600));
fetcher->delegate()->OnURLFetchComplete(fetcher);
EXPECT_EQ(3, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
EXPECT_EQ("token2", consumer_.last_token_);
}
...@@ -965,6 +965,8 @@ ...@@ -965,6 +965,8 @@
'browser/managed_mode/managed_user_service.h', 'browser/managed_mode/managed_user_service.h',
'browser/managed_mode/managed_user_service_factory.cc', 'browser/managed_mode/managed_user_service_factory.cc',
'browser/managed_mode/managed_user_service_factory.h', 'browser/managed_mode/managed_user_service_factory.h',
'browser/managed_mode/managed_user_refresh_token_fetcher.cc',
'browser/managed_mode/managed_user_refresh_token_fetcher.h',
'browser/media/audio_stream_indicator.cc', 'browser/media/audio_stream_indicator.cc',
'browser/media/audio_stream_indicator.h', 'browser/media/audio_stream_indicator.h',
'browser/media/media_capture_devices_dispatcher.cc', 'browser/media/media_capture_devices_dispatcher.cc',
......
...@@ -915,6 +915,7 @@ ...@@ -915,6 +915,7 @@
'browser/managed_mode/managed_user_passphrase_unittest.cc', 'browser/managed_mode/managed_user_passphrase_unittest.cc',
'browser/managed_mode/managed_user_registration_service_unittest.cc', 'browser/managed_mode/managed_user_registration_service_unittest.cc',
'browser/managed_mode/managed_user_service_unittest.cc', 'browser/managed_mode/managed_user_service_unittest.cc',
'browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc',
'browser/media_galleries/fileapi/itunes_finder_win_unittest.cc', 'browser/media_galleries/fileapi/itunes_finder_win_unittest.cc',
'browser/media_galleries/fileapi/native_media_file_util_unittest.cc', 'browser/media_galleries/fileapi/native_media_file_util_unittest.cc',
'browser/media_galleries/fileapi/picasa/picasa_album_table_reader_unittest.cc', 'browser/media_galleries/fileapi/picasa/picasa_album_table_reader_unittest.cc',
......
...@@ -203,7 +203,7 @@ void GaiaOAuthClient::Core::HandleResponse( ...@@ -203,7 +203,7 @@ void GaiaOAuthClient::Core::HandleResponse(
// If we don't have an access token yet and the the error was not // If we don't have an access token yet and the the error was not
// RC_BAD_REQUEST, we may need to retry. // RC_BAD_REQUEST, we may need to retry.
if ((source->GetMaxRetriesOn5xx() != -1) && if ((source->GetMaxRetriesOn5xx() != -1) &&
(num_retries_ > source->GetMaxRetriesOn5xx())) { (num_retries_ >= source->GetMaxRetriesOn5xx())) {
// Retry limit reached. Give up. // Retry limit reached. Give up.
delegate_->OnNetworkError(source->GetResponseCode()); delegate_->OnNetworkError(source->GetResponseCode());
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment