Commit 4e52bf06 authored by rickcam@chromium.org's avatar rickcam@chromium.org

BUG=91661

TEST=unit


Review URL: http://codereview.chromium.org/7574009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95523 0039d316-1c4b-4281-b951-d872f2087c98
parent b2519c18
...@@ -156,7 +156,6 @@ class OAuthLoginVerifier : public GaiaOAuthConsumer { ...@@ -156,7 +156,6 @@ class OAuthLoginVerifier : public GaiaOAuthConsumer {
: oauth_fetcher_(this, : oauth_fetcher_(this,
user_profile->GetOffTheRecordProfile()->GetRequestContext(), user_profile->GetOffTheRecordProfile()->GetRequestContext(),
user_profile->GetOffTheRecordProfile(), user_profile->GetOffTheRecordProfile(),
GaiaConstants::kSyncService,
kServiceScopeChromeOS), kServiceScopeChromeOS),
oauth1_token_(oauth1_token), oauth1_token_(oauth1_token),
oauth1_secret_(oauth1_secret) { oauth1_secret_(oauth1_secret) {
...@@ -201,7 +200,6 @@ class PolicyOAuthFetcher : public GaiaOAuthConsumer { ...@@ -201,7 +200,6 @@ class PolicyOAuthFetcher : public GaiaOAuthConsumer {
: oauth_fetcher_(this, : oauth_fetcher_(this,
profile->GetRequestContext(), profile->GetRequestContext(),
profile, profile,
GaiaConstants::kDeviceManagementService,
kServiceScopeChromeOSDeviceManagement), kServiceScopeChromeOSDeviceManagement),
oauth1_token_(oauth1_token), oauth1_token_(oauth1_token),
oauth1_secret_(oauth1_secret) { oauth1_secret_(oauth1_secret) {
...@@ -211,8 +209,8 @@ class PolicyOAuthFetcher : public GaiaOAuthConsumer { ...@@ -211,8 +209,8 @@ class PolicyOAuthFetcher : public GaiaOAuthConsumer {
virtual ~PolicyOAuthFetcher() {} virtual ~PolicyOAuthFetcher() {}
void Start() { void Start() {
oauth_fetcher_.StartOAuthWrapBridge(oauth1_token_, oauth1_secret_, "3600", oauth_fetcher_.StartOAuthWrapBridge(
std::string(GaiaConstants::kDeviceManagementService), oauth1_token_, oauth1_secret_, GaiaConstants::kGaiaOAuthDuration,
std::string(kServiceScopeChromeOSDeviceManagement)); std::string(kServiceScopeChromeOSDeviceManagement));
} }
...@@ -227,8 +225,9 @@ class PolicyOAuthFetcher : public GaiaOAuthConsumer { ...@@ -227,8 +225,9 @@ class PolicyOAuthFetcher : public GaiaOAuthConsumer {
} }
virtual void OnOAuthWrapBridgeFailure( virtual void OnOAuthWrapBridgeFailure(
const std::string& service_name,
const GoogleServiceAuthError& error) OVERRIDE { const GoogleServiceAuthError& error) OVERRIDE {
LOG(WARNING) << "Failed to get OAuth access token."; LOG(WARNING) << "Failed to get OAuth access token for " << service_name;
} }
private: private:
...@@ -569,7 +568,6 @@ void LoginUtilsImpl::FetchOAuth1AccessToken(Profile* auth_profile) { ...@@ -569,7 +568,6 @@ void LoginUtilsImpl::FetchOAuth1AccessToken(Profile* auth_profile) {
oauth_fetcher_.reset(new GaiaOAuthFetcher(this, oauth_fetcher_.reset(new GaiaOAuthFetcher(this,
auth_profile->GetRequestContext(), auth_profile->GetRequestContext(),
auth_profile, auth_profile,
GaiaConstants::kSyncService,
kServiceScopeChromeOS)); kServiceScopeChromeOS));
// Let's first get the Oauth request token and OAuth1 token+secret. // Let's first get the Oauth request token and OAuth1 token+secret.
// One we get that, we will kick off individial requests for OAuth2 tokens for // One we get that, we will kick off individial requests for OAuth2 tokens for
......
...@@ -26,8 +26,7 @@ namespace { ...@@ -26,8 +26,7 @@ namespace {
// The service scope of the OAuth v2 token that ChromeOS login will be // The service scope of the OAuth v2 token that ChromeOS login will be
// requesting. // requesting.
const char kServiceScopeChromeOS[] = const char* kServiceScopeChromeOS = GaiaConstants::kSyncServiceOAuth;
"https://www.googleapis.com/auth/chromesync";
} }
...@@ -63,7 +62,6 @@ void OnlineAttempt::Initiate(Profile* auth_profile) { ...@@ -63,7 +62,6 @@ void OnlineAttempt::Initiate(Profile* auth_profile) {
new GaiaOAuthFetcher(this, new GaiaOAuthFetcher(this,
auth_profile->GetRequestContext(), auth_profile->GetRequestContext(),
auth_profile, auth_profile,
GaiaConstants::kSyncService,
kServiceScopeChromeOS)); kServiceScopeChromeOS));
} else { } else {
client_fetcher_.reset( client_fetcher_.reset(
......
...@@ -24,10 +24,11 @@ class GaiaOAuthConsumer { ...@@ -24,10 +24,11 @@ class GaiaOAuthConsumer {
virtual void OnOAuthGetAccessTokenFailure( virtual void OnOAuthGetAccessTokenFailure(
const GoogleServiceAuthError& error) {} const GoogleServiceAuthError& error) {}
virtual void OnOAuthWrapBridgeSuccess(const std::string& service_name, virtual void OnOAuthWrapBridgeSuccess(const std::string& service_scope,
const std::string& token, const std::string& token,
const std::string& expires_in) {} const std::string& expires_in) {}
virtual void OnOAuthWrapBridgeFailure(const GoogleServiceAuthError& error) {} virtual void OnOAuthWrapBridgeFailure(const std::string& service_scope,
const GoogleServiceAuthError& error) {}
virtual void OnUserInfoSuccess(const std::string& email) {} virtual void OnUserInfoSuccess(const std::string& email) {}
virtual void OnUserInfoFailure(const GoogleServiceAuthError& error) {} virtual void OnUserInfoFailure(const GoogleServiceAuthError& error) {}
......
...@@ -54,13 +54,11 @@ static const char kOAuthTokenCookie[] = "oauth_token"; ...@@ -54,13 +54,11 @@ static const char kOAuthTokenCookie[] = "oauth_token";
GaiaOAuthFetcher::GaiaOAuthFetcher(GaiaOAuthConsumer* consumer, GaiaOAuthFetcher::GaiaOAuthFetcher(GaiaOAuthConsumer* consumer,
net::URLRequestContextGetter* getter, net::URLRequestContextGetter* getter,
Profile* profile, Profile* profile,
const std::string& service_name,
const std::string& service_scope) const std::string& service_scope)
: consumer_(consumer), : consumer_(consumer),
getter_(getter), getter_(getter),
profile_(profile), profile_(profile),
popup_(NULL), popup_(NULL),
service_name_(service_name),
service_scope_(service_scope), service_scope_(service_scope),
fetch_pending_(false), fetch_pending_(false),
auto_fetch_limit_(ALL_OAUTH_STEPS) {} auto_fetch_limit_(ALL_OAUTH_STEPS) {}
...@@ -408,14 +406,13 @@ void GaiaOAuthFetcher::StartOAuthWrapBridge( ...@@ -408,14 +406,13 @@ void GaiaOAuthFetcher::StartOAuthWrapBridge(
const std::string& oauth1_access_token, const std::string& oauth1_access_token,
const std::string& oauth1_access_token_secret, const std::string& oauth1_access_token_secret,
const std::string& wrap_token_duration, const std::string& wrap_token_duration,
const std::string& service_name,
const std::string& service_scope) { const std::string& service_scope) {
DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
VLOG(1) << "Starting OAuthWrapBridge for: " << service_name; VLOG(1) << "Starting OAuthWrapBridge for: " << service_scope;
std::string combined_scope = service_scope + " " + std::string combined_scope = service_scope + " " +
kOAuthWrapBridgeUserInfoScope; kOAuthWrapBridgeUserInfoScope;
service_name_ = service_name; service_scope_ = service_scope;
// Must outlive fetcher_. // Must outlive fetcher_.
request_body_ = MakeOAuthWrapBridgeBody( request_body_ = MakeOAuthWrapBridgeBody(
...@@ -595,7 +592,7 @@ void GaiaOAuthFetcher::OnOAuthGetAccessTokenFetched( ...@@ -595,7 +592,7 @@ void GaiaOAuthFetcher::OnOAuthGetAccessTokenFetched(
consumer_->OnOAuthGetAccessTokenSuccess(token, secret); consumer_->OnOAuthGetAccessTokenSuccess(token, secret);
if (ShouldAutoFetch(OAUTH2_SERVICE_ACCESS_TOKEN)) if (ShouldAutoFetch(OAUTH2_SERVICE_ACCESS_TOKEN))
StartOAuthWrapBridge( StartOAuthWrapBridge(
token, secret, "3600", service_name_, service_scope_); token, secret, GaiaConstants::kGaiaOAuthDuration, service_scope_);
} else { } else {
consumer_->OnOAuthGetAccessTokenFailure(GenerateAuthError(data, status)); consumer_->OnOAuthGetAccessTokenFailure(GenerateAuthError(data, status));
} }
...@@ -610,11 +607,12 @@ void GaiaOAuthFetcher::OnOAuthWrapBridgeFetched( ...@@ -610,11 +607,12 @@ void GaiaOAuthFetcher::OnOAuthWrapBridgeFetched(
std::string token; std::string token;
std::string expires_in; std::string expires_in;
ParseOAuthWrapBridgeResponse(data, &token, &expires_in); ParseOAuthWrapBridgeResponse(data, &token, &expires_in);
consumer_->OnOAuthWrapBridgeSuccess(service_name_, token, expires_in); consumer_->OnOAuthWrapBridgeSuccess(service_scope_, token, expires_in);
if (ShouldAutoFetch(USER_INFO)) if (ShouldAutoFetch(USER_INFO))
StartUserInfo(token); StartUserInfo(token);
} else { } else {
consumer_->OnOAuthWrapBridgeFailure(GenerateAuthError(data, status)); consumer_->OnOAuthWrapBridgeFailure(service_scope_,
GenerateAuthError(data, status));
} }
} }
......
...@@ -53,7 +53,6 @@ class GaiaOAuthFetcher : public URLFetcher::Delegate, ...@@ -53,7 +53,6 @@ class GaiaOAuthFetcher : public URLFetcher::Delegate,
GaiaOAuthFetcher(GaiaOAuthConsumer* consumer, GaiaOAuthFetcher(GaiaOAuthConsumer* consumer,
net::URLRequestContextGetter* getter, net::URLRequestContextGetter* getter,
Profile* profile, Profile* profile,
const std::string& service_name,
const std::string& service_scope); const std::string& service_scope);
virtual ~GaiaOAuthFetcher(); virtual ~GaiaOAuthFetcher();
...@@ -93,14 +92,13 @@ class GaiaOAuthFetcher : public URLFetcher::Delegate, ...@@ -93,14 +92,13 @@ class GaiaOAuthFetcher : public URLFetcher::Delegate,
// wrap_token_duration is typically one hour, // wrap_token_duration is typically one hour,
// which is also the max -- you can only decrease it. // which is also the max -- you can only decrease it.
// //
// service_name and service_scope should be specific to a service. For // service_scope will be used as a service name. For example, Chromium Sync
// example, Chromium Sync uses https://www.googleapis.com/auth/chromesync as // uses https://www.googleapis.com/auth/chromesync for its OAuth2 service
// its OAuth2 service scope. // scope here as well as for its service name in TokenService.
virtual void StartOAuthWrapBridge( virtual void StartOAuthWrapBridge(
const std::string& oauth1_access_token, const std::string& oauth1_access_token,
const std::string& oauth1_access_token_secret, const std::string& oauth1_access_token_secret,
const std::string& wrap_token_duration, const std::string& wrap_token_duration,
const std::string& service_name,
const std::string& service_scope); const std::string& service_scope);
// Obtains user information related to an OAuth2 access token // Obtains user information related to an OAuth2 access token
...@@ -240,7 +238,6 @@ class GaiaOAuthFetcher : public URLFetcher::Delegate, ...@@ -240,7 +238,6 @@ class GaiaOAuthFetcher : public URLFetcher::Delegate,
scoped_ptr<URLFetcher> fetcher_; scoped_ptr<URLFetcher> fetcher_;
std::string request_body_; std::string request_body_;
std::string request_headers_; std::string request_headers_;
std::string service_name_;
std::string service_scope_; std::string service_scope_;
bool fetch_pending_; bool fetch_pending_;
AutoFetchLimit auto_fetch_limit_; AutoFetchLimit auto_fetch_limit_;
......
...@@ -65,11 +65,12 @@ class MockGaiaOAuthConsumer : public GaiaOAuthConsumer { ...@@ -65,11 +65,12 @@ class MockGaiaOAuthConsumer : public GaiaOAuthConsumer {
void(const GoogleServiceAuthError& error)); void(const GoogleServiceAuthError& error));
MOCK_METHOD3(OnOAuthWrapBridgeSuccess, MOCK_METHOD3(OnOAuthWrapBridgeSuccess,
void(const std::string& service_name, void(const std::string& service_scope,
const std::string& token, const std::string& token,
const std::string& expires_in)); const std::string& expires_in));
MOCK_METHOD1(OnOAuthWrapBridgeFailure, MOCK_METHOD2(OnOAuthWrapBridgeFailure,
void(const GoogleServiceAuthError& error)); void(const std::string& service_scope,
const GoogleServiceAuthError& error));
MOCK_METHOD1(OnUserInfoSuccess, void(const std::string& email)); MOCK_METHOD1(OnUserInfoSuccess, void(const std::string& email));
MOCK_METHOD1(OnUserInfoFailure, void(const GoogleServiceAuthError& error)); MOCK_METHOD1(OnUserInfoFailure, void(const GoogleServiceAuthError& error));
...@@ -80,21 +81,19 @@ class MockGaiaOAuthFetcher : public GaiaOAuthFetcher { ...@@ -80,21 +81,19 @@ class MockGaiaOAuthFetcher : public GaiaOAuthFetcher {
MockGaiaOAuthFetcher(GaiaOAuthConsumer* consumer, MockGaiaOAuthFetcher(GaiaOAuthConsumer* consumer,
net::URLRequestContextGetter* getter, net::URLRequestContextGetter* getter,
Profile* profile, Profile* profile,
const std::string& service_name,
const std::string& service_scope) const std::string& service_scope)
: GaiaOAuthFetcher( : GaiaOAuthFetcher(
consumer, getter, profile, service_name, service_scope) {} consumer, getter, profile, service_scope) {}
~MockGaiaOAuthFetcher() {} ~MockGaiaOAuthFetcher() {}
MOCK_METHOD1(StartOAuthGetAccessToken, MOCK_METHOD1(StartOAuthGetAccessToken,
void(const std::string& oauth1_request_token)); void(const std::string& oauth1_request_token));
MOCK_METHOD5(StartOAuthWrapBridge, MOCK_METHOD4(StartOAuthWrapBridge,
void(const std::string& oauth1_access_token, void(const std::string& oauth1_access_token,
const std::string& oauth1_access_token_secret, const std::string& oauth1_access_token_secret,
const std::string& wrap_token_duration, const std::string& wrap_token_duration,
const std::string& service_name,
const std::string& oauth2_scope)); const std::string& oauth2_scope));
MOCK_METHOD1(StartUserInfo, void(const std::string& oauth2_access_token)); MOCK_METHOD1(StartUserInfo, void(const std::string& oauth2_access_token));
...@@ -151,8 +150,9 @@ TEST(GaiaOAuthFetcherTest, GetOAuthToken) { ...@@ -151,8 +150,9 @@ TEST(GaiaOAuthFetcherTest, GetOAuthToken) {
typedef TestingBrowserProcessTest GaiaOAuthFetcherTest; typedef TestingBrowserProcessTest GaiaOAuthFetcherTest;
TEST_F(GaiaOAuthFetcherTest, OAuthGetAccessToken) { TEST_F(GaiaOAuthFetcherTest, OAuthGetAccessToken) {
const std::string oauth_token="1/OAuth1-Access_Token-1234567890abcdefghijklm"; const std::string oauth_token =
const std::string oauth_token_secret="Dont_tell_the_secret-123"; "1/OAuth1-Access_Token-1234567890abcdefghijklm";
const std::string oauth_token_secret = "Dont_tell_the_secret-123";
const std::string data("oauth_token=" const std::string data("oauth_token="
"1%2FOAuth1-Access_Token-1234567890abcdefghijklm" "1%2FOAuth1-Access_Token-1234567890abcdefghijklm"
"&oauth_token_secret=Dont_tell_the_secret-123"); "&oauth_token_secret=Dont_tell_the_secret-123");
...@@ -166,13 +166,11 @@ TEST_F(GaiaOAuthFetcherTest, OAuthGetAccessToken) { ...@@ -166,13 +166,11 @@ TEST_F(GaiaOAuthFetcherTest, OAuthGetAccessToken) {
MockGaiaOAuthFetcher oauth_fetcher(&consumer, MockGaiaOAuthFetcher oauth_fetcher(&consumer,
profile.GetRequestContext(), profile.GetRequestContext(),
&profile, &profile,
"service_name-eKARPyky",
"service_scope-JnG18MEE"); "service_scope-JnG18MEE");
EXPECT_CALL(oauth_fetcher, EXPECT_CALL(oauth_fetcher,
StartOAuthWrapBridge(oauth_token, StartOAuthWrapBridge(oauth_token,
oauth_token_secret, oauth_token_secret,
"3600", "3600",
"service_name-eKARPyky",
"service_scope-JnG18MEE")).Times(1); "service_scope-JnG18MEE")).Times(1);
net::ResponseCookies cookies; net::ResponseCookies cookies;
...@@ -186,8 +184,9 @@ TEST_F(GaiaOAuthFetcherTest, OAuthGetAccessToken) { ...@@ -186,8 +184,9 @@ TEST_F(GaiaOAuthFetcherTest, OAuthGetAccessToken) {
} }
TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) { TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) {
const std::string wrap_token="1/OAuth2-Access_Token-nopqrstuvwxyz1234567890"; const std::string wrap_token =
const std::string expires_in="3600"; "1/OAuth2-Access_Token-nopqrstuvwxyz1234567890";
const std::string expires_in = "3600";
const std::string data("wrap_access_token=" const std::string data("wrap_access_token="
"1%2FOAuth2-Access_Token-nopqrstuvwxyz1234567890" "1%2FOAuth2-Access_Token-nopqrstuvwxyz1234567890"
...@@ -195,7 +194,7 @@ TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) { ...@@ -195,7 +194,7 @@ TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) {
MockGaiaOAuthConsumer consumer; MockGaiaOAuthConsumer consumer;
EXPECT_CALL(consumer, EXPECT_CALL(consumer,
OnOAuthWrapBridgeSuccess("service_name-62Ykg3K1", OnOAuthWrapBridgeSuccess("service_scope-0fL85iOi",
wrap_token, wrap_token,
expires_in)).Times(1); expires_in)).Times(1);
...@@ -203,7 +202,6 @@ TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) { ...@@ -203,7 +202,6 @@ TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) {
MockGaiaOAuthFetcher oauth_fetcher(&consumer, MockGaiaOAuthFetcher oauth_fetcher(&consumer,
profile .GetRequestContext(), profile .GetRequestContext(),
&profile, &profile,
"service_name-62Ykg3K1",
"service_scope-0fL85iOi"); "service_scope-0fL85iOi");
EXPECT_CALL(oauth_fetcher, StartUserInfo(wrap_token)).Times(1); EXPECT_CALL(oauth_fetcher, StartUserInfo(wrap_token)).Times(1);
...@@ -218,9 +216,10 @@ TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) { ...@@ -218,9 +216,10 @@ TEST_F(GaiaOAuthFetcherTest, OAuthWrapBridge) {
} }
TEST_F(GaiaOAuthFetcherTest, UserInfo) { TEST_F(GaiaOAuthFetcherTest, UserInfo) {
const std::string email_address="someone@somewhere.net"; const std::string email_address = "someone@somewhere.net";
const std::string wrap_token="1/OAuth2-Access_Token-nopqrstuvwxyz1234567890"; const std::string wrap_token =
const std::string expires_in="3600"; "1/OAuth2-Access_Token-nopqrstuvwxyz1234567890";
const std::string expires_in = "3600";
const std::string data("{\n \"email\": \"someone@somewhere.net\",\n" const std::string data("{\n \"email\": \"someone@somewhere.net\",\n"
" \"verified_email\": true\n}\n"); " \"verified_email\": true\n}\n");
MockGaiaOAuthConsumer consumer; MockGaiaOAuthConsumer consumer;
...@@ -231,7 +230,6 @@ TEST_F(GaiaOAuthFetcherTest, UserInfo) { ...@@ -231,7 +230,6 @@ TEST_F(GaiaOAuthFetcherTest, UserInfo) {
MockGaiaOAuthFetcher oauth_fetcher(&consumer, MockGaiaOAuthFetcher oauth_fetcher(&consumer,
profile .GetRequestContext(), profile .GetRequestContext(),
&profile, &profile,
"service_name-S2igVNUm",
"service_scope-Nrj4LmgU"); "service_scope-Nrj4LmgU");
net::ResponseCookies cookies; net::ResponseCookies cookies;
......
...@@ -26,8 +26,17 @@ const char* TokenService::kServices[] = { ...@@ -26,8 +26,17 @@ const char* TokenService::kServices[] = {
GaiaConstants::kDeviceManagementService 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() TokenService::TokenService()
: token_loading_query_(0) { : profile_(NULL),
token_loading_query_(0) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
} }
...@@ -44,6 +53,8 @@ void TokenService::Initialize(const char* const source, ...@@ -44,6 +53,8 @@ void TokenService::Initialize(const char* const source,
// Already initialized. // Already initialized.
return; return;
} }
DCHECK(!profile_);
profile_ = profile;
getter_ = profile->GetRequestContext(); getter_ = profile->GetRequestContext();
// Since the user can create a bookmark in incognito, sync may be running. // Since the user can create a bookmark in incognito, sync may be running.
// Thus we have to go for explicit access. // Thus we have to go for explicit access.
...@@ -76,9 +87,12 @@ void TokenService::ResetCredentialsInMemory() { ...@@ -76,9 +87,12 @@ void TokenService::ResetCredentialsInMemory() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Terminate any running fetchers. Callbacks will not return. // 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(); fetchers_[i].reset();
} }
for (int i = 0; i < kNumOAuthServices; ++i) {
oauth_fetchers_[i].reset();
}
// Cancel pending loads. Callbacks will not return. // Cancel pending loads. Callbacks will not return.
if (token_loading_query_) { if (token_loading_query_) {
...@@ -88,6 +102,8 @@ void TokenService::ResetCredentialsInMemory() { ...@@ -88,6 +102,8 @@ void TokenService::ResetCredentialsInMemory() {
token_map_.clear(); token_map_.clear();
credentials_ = GaiaAuthConsumer::ClientLoginResult(); credentials_ = GaiaAuthConsumer::ClientLoginResult();
oauth_token_.clear();
oauth_secret_.clear();
} }
void TokenService::UpdateCredentials( void TokenService::UpdateCredentials(
...@@ -104,6 +120,23 @@ 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() { void TokenService::LoadTokensFromDB() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (web_data_service_.get()) if (web_data_service_.get())
...@@ -127,6 +160,10 @@ bool TokenService::AreCredentialsValid() const { ...@@ -127,6 +160,10 @@ bool TokenService::AreCredentialsValid() const {
return !credentials_.lsid.empty() && !credentials_.sid.empty(); return !credentials_.lsid.empty() && !credentials_.sid.empty();
} }
bool TokenService::AreOAuthCredentialsValid() const {
return !oauth_token_.empty() && !oauth_secret_.empty();
}
bool TokenService::HasLsid() const { bool TokenService::HasLsid() const {
return !credentials_.lsid.empty(); return !credentials_.lsid.empty();
} }
...@@ -145,6 +182,17 @@ void TokenService::StartFetchingTokens() { ...@@ -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. // 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. // If it isn't, they'll go to sleep until they get a token event.
bool TokenService::HasTokenForService(const char* const service) const { bool TokenService::HasTokenForService(const char* const service) const {
...@@ -210,6 +258,38 @@ void TokenService::OnIssueAuthTokenFailure(const std::string& service, ...@@ -210,6 +258,38 @@ void TokenService::OnIssueAuthTokenFailure(const std::string& service,
FireTokenRequestFailedNotification(service, error); 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);
}
void TokenService::OnWebDataServiceRequestDone(WebDataService::Handle h, void TokenService::OnWebDataServiceRequestDone(WebDataService::Handle h,
const WDTypedResult* result) { const WDTypedResult* result) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
...@@ -277,6 +357,45 @@ void TokenService::LoadTokensIntoMemory( ...@@ -277,6 +357,45 @@ void TokenService::LoadTokensIntoMemory(
std::string())); 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, void TokenService::Observe(int type,
......
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
// //
// The TokenService will supply authentication tokens for any service that // The TokenService will supply authentication tokens for any service that
// needs it, such as sync. Whenever the user logs in, a controller watching // needs it, such as sync. Whenever the user logs in, a controller watching
// the token service is expected to call ClientLogin to derive a new SID and // the token service is expected either to call ClientLogin to derive a new
// LSID. Whenever such credentials are available, the TokenService should be // SID and LSID, or to use GAIA OAuth requests to derive an OAuth1 access
// updated with new credentials. The controller should then start fetching // token for the OAuthLogin scope. Whenever such credentials are available,
// tokens, which will be written to the database after retrieval, as well as // the TokenService should be updated with new credentials. The controller
// provided to listeners. // should then start fetching tokens, which will be written to the database
// after retrieval, as well as provided to listeners.
// //
// A token service controller like the ChromiumOS login is expected to: // A token service controller like the ChromiumOS login is expected to:
// //
...@@ -40,6 +41,8 @@ ...@@ -40,6 +41,8 @@
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "chrome/browser/net/gaia/gaia_oauth_consumer.h"
#include "chrome/browser/net/gaia/gaia_oauth_fetcher.h"
#include "chrome/browser/webdata/web_data_service.h" #include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/net/gaia/gaia_auth_consumer.h" #include "chrome/common/net/gaia/gaia_auth_consumer.h"
#include "chrome/common/net/gaia/gaia_auth_fetcher.h" #include "chrome/common/net/gaia/gaia_auth_fetcher.h"
...@@ -56,6 +59,7 @@ class URLRequestContextGetter; ...@@ -56,6 +59,7 @@ class URLRequestContextGetter;
// The TokenService is a Profile member, so all calls are expected // The TokenService is a Profile member, so all calls are expected
// from the UI thread. // from the UI thread.
class TokenService : public GaiaAuthConsumer, class TokenService : public GaiaAuthConsumer,
public GaiaOAuthConsumer,
public WebDataServiceConsumer, public WebDataServiceConsumer,
public NotificationObserver { public NotificationObserver {
public: public:
...@@ -98,16 +102,23 @@ class TokenService : public GaiaAuthConsumer, ...@@ -98,16 +102,23 @@ class TokenService : public GaiaAuthConsumer,
// Used to determine whether Initialize() has been called. // Used to determine whether Initialize() has been called.
bool Initialized() const { return !source_.empty(); } bool Initialized() const { return !source_.empty(); }
// Update the credentials in the token service. // Update ClientLogin credentials in the token service.
// Afterwards you can StartFetchingTokens. // Afterwards you can StartFetchingTokens.
void UpdateCredentials( void UpdateCredentials(
const GaiaAuthConsumer::ClientLoginResult& credentials); const GaiaAuthConsumer::ClientLoginResult& credentials);
// Update OAuth credentials in the token service.
// Afterwards you can StartFetchingOAuthTokens.
void UpdateOAuthCredentials(
const std::string& oauth_token,
const std::string& oauth_secret);
// Terminate any running requests and reset the TokenService to a clean // Terminate any running requests and reset the TokenService to a clean
// slate. Resets in memory structures. Does not modify the DB. // slate. Resets in memory structures. Does not modify the DB.
// When this is done, no tokens will be left in memory and no // When this is done, no tokens will be left in memory and no
// user credentials will be left. Useful if a user is logging out. // user credentials will be left. Useful if a user is logging out.
// Initialize doesn't need to be called again but UpdateCredentials does. // Initialize doesn't need to be called again but UpdateCredentials and
// UpdateOAuthCredentials do.
void ResetCredentialsInMemory(); void ResetCredentialsInMemory();
// Async load all tokens for services we know of from the DB. // Async load all tokens for services we know of from the DB.
...@@ -125,11 +136,14 @@ class TokenService : public GaiaAuthConsumer, ...@@ -125,11 +136,14 @@ class TokenService : public GaiaAuthConsumer,
const std::string& GetLsid() const; const std::string& GetLsid() const;
// Did we get a proper LSID? // Did we get a proper LSID?
bool AreCredentialsValid() const; bool AreCredentialsValid() const;
// Do we have an OAuth access token and secret.
bool AreOAuthCredentialsValid() const;
// Tokens will be fetched for all services(sync, talk) in the background. // Tokens will be fetched for all services(sync, talk) in the background.
// Results come back via event channel. Services can also poll before events // Results come back via event channel. Services can also poll before events
// are issued. // are issued.
void StartFetchingTokens(); void StartFetchingTokens();
void StartFetchingOAuthTokens();
bool HasTokenForService(const char* const service) const; bool HasTokenForService(const char* const service) const;
const std::string& GetTokenForService(const char* const service) const; const std::string& GetTokenForService(const char* const service) const;
...@@ -139,9 +153,23 @@ class TokenService : public GaiaAuthConsumer, ...@@ -139,9 +153,23 @@ class TokenService : public GaiaAuthConsumer,
// GaiaAuthConsumer implementation. // GaiaAuthConsumer implementation.
virtual void OnIssueAuthTokenSuccess(const std::string& service, virtual void OnIssueAuthTokenSuccess(const std::string& service,
const std::string& auth_token); const std::string& auth_token) OVERRIDE;
virtual void OnIssueAuthTokenFailure(const std::string& service, virtual void OnIssueAuthTokenFailure(const std::string& service,
const GoogleServiceAuthError& error); const GoogleServiceAuthError& error)
OVERRIDE;
// GaiaOAuthConsumer implementation.
virtual void OnOAuthGetAccessTokenSuccess(const std::string& token,
const std::string& secret) OVERRIDE;
virtual void OnOAuthGetAccessTokenFailure(
const GoogleServiceAuthError& error) OVERRIDE;
virtual void OnOAuthWrapBridgeSuccess(const std::string& service_scope,
const std::string& token,
const std::string& expires_in) OVERRIDE;
virtual void OnOAuthWrapBridgeFailure(const std::string& service_name,
const GoogleServiceAuthError& error)
OVERRIDE;
// WebDataServiceConsumer implementation. // WebDataServiceConsumer implementation.
virtual void OnWebDataServiceRequestDone(WebDataService::Handle h, virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
...@@ -166,6 +194,9 @@ class TokenService : public GaiaAuthConsumer, ...@@ -166,6 +194,9 @@ class TokenService : public GaiaAuthConsumer,
void SaveAuthTokenToDB(const std::string& service, void SaveAuthTokenToDB(const std::string& service,
const std::string& auth_token); const std::string& auth_token);
// The profile with which this instance was initialized, or NULL.
Profile* profile_;
// Web data service to access tokens from. // Web data service to access tokens from.
scoped_refptr<WebDataService> web_data_service_; scoped_refptr<WebDataService> web_data_service_;
// Getter to use for fetchers. // Getter to use for fetchers.
...@@ -177,14 +208,36 @@ class TokenService : public GaiaAuthConsumer, ...@@ -177,14 +208,36 @@ class TokenService : public GaiaAuthConsumer,
std::string source_; std::string source_;
// Credentials from ClientLogin for Issuing auth tokens. // Credentials from ClientLogin for Issuing auth tokens.
GaiaAuthConsumer::ClientLoginResult credentials_; GaiaAuthConsumer::ClientLoginResult credentials_;
// Credentials from Gaia OAuth (uber/login token)
// Size of array of services (must be defined here). std::string oauth_token_;
std::string oauth_secret_;
// Size of array of services capable of ClientLogin-based authentication.
// This value must be defined here.
// NOTE: The use of --enable-sync-oauth does not affect this count. The
// TokenService can continue to do some degree of ClientLogin token
// management, mostly related to persistence while Sync and possibly other
// services are using OAuth-based authentication.
static const int kNumServices = 4; static const int kNumServices = 4;
// List of services that we're performing operations for. // List of services that are capable of ClientLogin-based authentication.
static const char* kServices[kNumServices]; static const char* kServices[kNumServices];
// A bunch of fetchers suitable for token issuing. We don't care about // A bunch of fetchers suitable for ClientLogin token issuing. We don't care
// the ordering, nor do we care which is for which service. // about the ordering, nor do we care which is for which service.
scoped_ptr<GaiaAuthFetcher> fetchers_[kNumServices]; scoped_ptr<GaiaAuthFetcher> fetchers_[kNumServices];
// Size of array of services capable of OAuth-based authentication. This
// value must be defined here.
// NOTE: The use of --enable-sync-oauth does not affect this count. The
// TokenService can continue to do some degree of OAuth token
// management, mostly related to persistence while Sync and possibly other
// services are using ClientLogin-based authentication.
static const int kNumOAuthServices = 1;
// List of services that are capable of OAuth-based authentication.
static const char* kOAuthServices[kNumOAuthServices];
// A bunch of fetchers suitable for OAuth token issuing. We don't care about
// the ordering, nor do we care which is for which service.
scoped_ptr<GaiaOAuthFetcher> oauth_fetchers_[kNumOAuthServices];
// Map from service to token. // Map from service to token.
std::map<std::string, std::string> token_map_; std::map<std::string, std::string> token_map_;
......
...@@ -76,6 +76,8 @@ class TokenServiceTestHarness : public TestingBrowserProcessTest { ...@@ -76,6 +76,8 @@ class TokenServiceTestHarness : public TestingBrowserProcessTest {
TokenAvailableTracker success_tracker_; TokenAvailableTracker success_tracker_;
TokenFailedTracker failure_tracker_; TokenFailedTracker failure_tracker_;
GaiaAuthConsumer::ClientLoginResult credentials_; GaiaAuthConsumer::ClientLoginResult credentials_;
std::string oauth_token_;
std::string oauth_secret_;
scoped_ptr<TestingProfile> profile_; scoped_ptr<TestingProfile> profile_;
}; };
......
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
const char kGetInfoEmailKey[] = "email"; const char kGetInfoEmailKey[] = "email";
const char kSyncOAuth2Scope[] = "https://www.googleapis.com/auth/chromesync";
SigninManager::SigninManager() SigninManager::SigninManager()
: profile_(NULL), had_two_factor_error_(false) {} : profile_(NULL), had_two_factor_error_(false) {}
...@@ -85,8 +83,7 @@ void SigninManager::StartOAuthSignIn() { ...@@ -85,8 +83,7 @@ void SigninManager::StartOAuthSignIn() {
oauth_login_.reset(new GaiaOAuthFetcher(this, oauth_login_.reset(new GaiaOAuthFetcher(this,
profile_->GetRequestContext(), profile_->GetRequestContext(),
profile_, profile_,
GaiaConstants::kSyncService, GaiaConstants::kSyncServiceOAuth));
kSyncOAuth2Scope));
oauth_login_->StartGetOAuthToken(); oauth_login_->StartGetOAuthToken();
} }
...@@ -246,6 +243,7 @@ void SigninManager::OnOAuthWrapBridgeSuccess(const std::string& service_name, ...@@ -246,6 +243,7 @@ void SigninManager::OnOAuthWrapBridgeSuccess(const std::string& service_name,
} }
void SigninManager::OnOAuthWrapBridgeFailure( void SigninManager::OnOAuthWrapBridgeFailure(
const std::string& service_scope,
const GoogleServiceAuthError& error) { const GoogleServiceAuthError& error) {
VLOG(1) << "SigninManager::OnOAuthWrapBridgeFailure"; VLOG(1) << "SigninManager::OnOAuthWrapBridgeFailure";
} }
......
...@@ -104,7 +104,8 @@ class SigninManager : public GaiaAuthConsumer, ...@@ -104,7 +104,8 @@ class SigninManager : public GaiaAuthConsumer,
const std::string& token, const std::string& token,
const std::string& expires_in) const std::string& expires_in)
OVERRIDE; OVERRIDE;
virtual void OnOAuthWrapBridgeFailure(const GoogleServiceAuthError& error); virtual void OnOAuthWrapBridgeFailure(const std::string& service_name,
const GoogleServiceAuthError& error);
virtual void OnUserInfoSuccess(const std::string& email) OVERRIDE; virtual void OnUserInfoSuccess(const std::string& email) OVERRIDE;
virtual void OnUserInfoFailure(const GoogleServiceAuthError& error) OVERRIDE; virtual void OnUserInfoFailure(const GoogleServiceAuthError& error) OVERRIDE;
......
...@@ -16,19 +16,28 @@ const char kChromeSource[] = "ChromiumBrowser"; ...@@ -16,19 +16,28 @@ const char kChromeSource[] = "ChromiumBrowser";
const char kGaiaService[] = "gaia"; const char kGaiaService[] = "gaia";
// Service name for Gaia Contacts API. API is used to get user's image. // Service name for Gaia Contacts API. API is used to get user's image.
const char kContactsService[] = "cp"; const char kContactsService[] = "cp";
// Service name for sync.
// Service/scope names for sync.
const char kSyncService[] = "chromiumsync"; const char kSyncService[] = "chromiumsync";
const char kSyncServiceOAuth[] = "https://www.googleapis.com/auth/chromesync";
// Service name for XMPP Google Talk. // Service name for XMPP Google Talk.
const char kTalkService[] = "talk"; const char kTalkService[] = "talk";
// Service name for remoting. // Service name for remoting.
const char kRemotingService[] = "chromoting"; const char kRemotingService[] = "chromoting";
// Service name for cloud print. // Service name for cloud print.
const char kCloudPrintService[] = "cloudprint"; const char kCloudPrintService[] = "cloudprint";
// Service name for device management (cloud-based policy) server.
// Service/scope names for device management (cloud-based policy) server.
const char kDeviceManagementService[] = "mobilesync"; const char kDeviceManagementService[] = "mobilesync";
const char kDeviceManagementServiceOAuth[] =
"https://www.googleapis.com/auth/chromeosdevicemanagement";
// Used to mint uber auth tokens when needed. // Used to mint uber auth tokens when needed.
const char kGaiaSid[] = "sid"; const char kGaiaSid[] = "sid";
const char kGaiaLsid[] = "lsid"; const char kGaiaLsid[] = "lsid";
extern const char kGaiaOAuthToken[] = "oauthToken";
extern const char kGaiaOAuthSecret[] = "oauthSecret";
extern const char kGaiaOAuthDuration[] = "3600";
} // namespace GaiaConstants } // namespace GaiaConstants
...@@ -18,13 +18,18 @@ extern const char kGaiaService[]; // uber token ...@@ -18,13 +18,18 @@ extern const char kGaiaService[]; // uber token
extern const char kContactsService[]; extern const char kContactsService[];
extern const char kTalkService[]; extern const char kTalkService[];
extern const char kSyncService[]; extern const char kSyncService[];
extern const char kSyncServiceOAuth[];
extern const char kRemotingService[]; extern const char kRemotingService[];
extern const char kCloudPrintService[]; extern const char kCloudPrintService[];
extern const char kDeviceManagementService[]; extern const char kDeviceManagementService[];
extern const char kDeviceManagementServiceOAuth[];
// Used to mint uber auth tokens when needed. // Used with uber auth tokens when needed.
extern const char kGaiaSid[]; extern const char kGaiaSid[];
extern const char kGaiaLsid[]; extern const char kGaiaLsid[];
extern const char kGaiaOAuthToken[];
extern const char kGaiaOAuthSecret[];
extern const char kGaiaOAuthDuration[];
} // namespace GaiaConstants } // namespace GaiaConstants
......
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