summaryrefslogtreecommitdiffstats
path: root/chrome/common/net
diff options
context:
space:
mode:
authorqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-19 09:37:18 +0000
committerqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-19 09:37:18 +0000
commitcc4dbe2b5fc29dd70f88272da7fc2a536de7ce51 (patch)
tree17a9de632df4287e98d2ca076a319a9f74675ada /chrome/common/net
parentd24b8c1e56e34a4e1040083189e5faf635154580 (diff)
downloadchromium_src-cc4dbe2b5fc29dd70f88272da7fc2a536de7ce51.zip
chromium_src-cc4dbe2b5fc29dd70f88272da7fc2a536de7ce51.tar.gz
chromium_src-cc4dbe2b5fc29dd70f88272da7fc2a536de7ce51.tar.bz2
Update API of OAuth2AccessTokenFetcher to return an expiration date.
OAuth2 access token have an expiration date that is returned by the server. Until now, we were not retrieving this information and had no way to reuse the tokens correctly. This change updates the API so this information is available to the caller. This is a reland of revision 147199. Original review: https://chromiumcodereview.appspot.com/10694154 TEST=None BUG=None TBR=munjal, kalman, Miranda Callahan, Ben Goodger (Google) R=tbarzic Review URL: https://chromiumcodereview.appspot.com/10796006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/net')
-rw-r--r--chrome/common/net/gaia/oauth2_access_token_consumer.h10
-rw-r--r--chrome/common/net/gaia/oauth2_access_token_fetcher.cc29
-rw-r--r--chrome/common/net/gaia/oauth2_access_token_fetcher.h10
-rw-r--r--chrome/common/net/gaia/oauth2_access_token_fetcher_unittest.cc18
-rw-r--r--chrome/common/net/gaia/oauth2_api_call_flow.cc3
-rw-r--r--chrome/common/net/gaia/oauth2_api_call_flow.h3
-rw-r--r--chrome/common/net/gaia/oauth2_api_call_flow_unittest.cc17
7 files changed, 68 insertions, 22 deletions
diff --git a/chrome/common/net/gaia/oauth2_access_token_consumer.h b/chrome/common/net/gaia/oauth2_access_token_consumer.h
index 0670d80..2c5d2a1 100644
--- a/chrome/common/net/gaia/oauth2_access_token_consumer.h
+++ b/chrome/common/net/gaia/oauth2_access_token_consumer.h
@@ -9,11 +9,19 @@
class GoogleServiceAuthError;
+namespace base {
+class Time;
+}
+
// An interface that defines the callbacks for consumers to which
// OAuth2AccessTokenFetcher can return results.
class OAuth2AccessTokenConsumer {
public:
- virtual void OnGetTokenSuccess(const std::string& access_token) {}
+ // Success callback. |access_token| will contain a valid OAuth2 access token.
+ // |expiration_time| is the date until which the token can be used. This
+ // value has a built-in safety margin, so it can be used as-is.
+ virtual void OnGetTokenSuccess(const std::string& access_token,
+ const base::Time& expiration_time) {}
virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) {}
protected:
diff --git a/chrome/common/net/gaia/oauth2_access_token_fetcher.cc b/chrome/common/net/gaia/oauth2_access_token_fetcher.cc
index 595ecae..e3d0180 100644
--- a/chrome/common/net/gaia/oauth2_access_token_fetcher.cc
+++ b/chrome/common/net/gaia/oauth2_access_token_fetcher.cc
@@ -11,6 +11,7 @@
#include "base/json/json_reader.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
+#include "base/time.h"
#include "base/values.h"
#include "chrome/common/net/gaia/gaia_urls.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
@@ -42,6 +43,7 @@ static const char kGetAccessTokenBodyWithScopeFormat[] =
"scope=%s";
static const char kAccessTokenKey[] = "access_token";
+static const char kExpiresInKey[] = "expires_in";
static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
CHECK(!status.is_success());
@@ -129,15 +131,26 @@ void OAuth2AccessTokenFetcher::EndGetAccessToken(
}
// The request was successfully fetched and it returned OK.
- // Parse out the access token.
+ // Parse out the access token and the expiration time.
std::string access_token;
- ParseGetAccessTokenResponse(source, &access_token);
- OnGetTokenSuccess(access_token);
+ int expires_in;
+ if (!ParseGetAccessTokenResponse(source, &access_token, &expires_in)) {
+ DLOG(WARNING) << "Response doesn't match expected format";
+ OnGetTokenFailure(
+ GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
+ return;
+ }
+ // The token will expire in |expires_in| seconds. Take a 10% error margin to
+ // prevent reusing a token too close to its expiration date.
+ OnGetTokenSuccess(
+ access_token,
+ base::Time::Now() + base::TimeDelta::FromSeconds(9 * expires_in / 10));
}
void OAuth2AccessTokenFetcher::OnGetTokenSuccess(
- const std::string& access_token) {
- consumer_->OnGetTokenSuccess(access_token);
+ const std::string& access_token,
+ const base::Time& expiration_time) {
+ consumer_->OnGetTokenSuccess(access_token, expiration_time);
}
void OAuth2AccessTokenFetcher::OnGetTokenFailure(
@@ -189,7 +202,8 @@ std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody(
// static
bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
const net::URLFetcher* source,
- std::string* access_token) {
+ std::string* access_token,
+ int* expires_in) {
CHECK(source);
CHECK(access_token);
std::string data;
@@ -199,5 +213,6 @@ bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
return false;
DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
- return dict->GetString(kAccessTokenKey, access_token);
+ return dict->GetString(kAccessTokenKey, access_token) &&
+ dict->GetInteger(kExpiresInKey, expires_in);
}
diff --git a/chrome/common/net/gaia/oauth2_access_token_fetcher.h b/chrome/common/net/gaia/oauth2_access_token_fetcher.h
index 61b7530..3242e62 100644
--- a/chrome/common/net/gaia/oauth2_access_token_fetcher.h
+++ b/chrome/common/net/gaia/oauth2_access_token_fetcher.h
@@ -16,6 +16,10 @@
class OAuth2AccessTokenFetcherTest;
+namespace base {
+class Time;
+}
+
namespace net {
class URLFetcher;
class URLRequestContextGetter;
@@ -75,7 +79,8 @@ class OAuth2AccessTokenFetcher : public net::URLFetcherDelegate {
void EndGetAccessToken(const net::URLFetcher* source);
// Helper mehtods for reporting back results.
- void OnGetTokenSuccess(const std::string& access_token);
+ void OnGetTokenSuccess(const std::string& access_token,
+ const base::Time& expiration_time);
void OnGetTokenFailure(const GoogleServiceAuthError& error);
// Other helpers.
@@ -86,7 +91,8 @@ class OAuth2AccessTokenFetcher : public net::URLFetcherDelegate {
const std::string& refresh_token,
const std::vector<std::string>& scopes);
static bool ParseGetAccessTokenResponse(const net::URLFetcher* source,
- std::string* access_token);
+ std::string* access_token,
+ int* expires_in);
// State that is set during construction.
OAuth2AccessTokenConsumer* const consumer_;
diff --git a/chrome/common/net/gaia/oauth2_access_token_fetcher_unittest.cc b/chrome/common/net/gaia/oauth2_access_token_fetcher_unittest.cc
index 013f23c..22b12a4 100644
--- a/chrome/common/net/gaia/oauth2_access_token_fetcher_unittest.cc
+++ b/chrome/common/net/gaia/oauth2_access_token_fetcher_unittest.cc
@@ -73,7 +73,8 @@ class MockOAuth2AccessTokenConsumer : public OAuth2AccessTokenConsumer {
MockOAuth2AccessTokenConsumer() {}
~MockOAuth2AccessTokenConsumer() {}
- MOCK_METHOD1(OnGetTokenSuccess, void(const std::string& access_token));
+ MOCK_METHOD2(OnGetTokenSuccess, void(const std::string& access_token,
+ const base::Time& expiration_time));
MOCK_METHOD1(OnGetTokenFailure,
void(const GoogleServiceAuthError& error));
};
@@ -137,7 +138,7 @@ TEST_F(OAuth2AccessTokenFetcherTest,
TEST_F(OAuth2AccessTokenFetcherTest, DISABLED_Success) {
TestURLFetcher* url_fetcher = SetupGetAccessToken(
true, net::HTTP_OK, kValidTokenResponse);
- EXPECT_CALL(consumer_, OnGetTokenSuccess("at1")).Times(1);
+ EXPECT_CALL(consumer_, OnGetTokenSuccess("at1", _)).Times(1);
fetcher_.Start("client_id", "client_secret", "refresh_token", ScopeList());
fetcher_.OnURLFetchComplete(url_fetcher);
}
@@ -195,8 +196,9 @@ TEST_F(OAuth2AccessTokenFetcherTest, MAYBE_ParseGetAccessTokenResponse) {
TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
std::string at;
+ int expires_in;
EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
- &url_fetcher, &at));
+ &url_fetcher, &at, &expires_in));
EXPECT_TRUE(at.empty());
}
{ // Bad json.
@@ -204,8 +206,9 @@ TEST_F(OAuth2AccessTokenFetcherTest, MAYBE_ParseGetAccessTokenResponse) {
url_fetcher.SetResponseString("foo");
std::string at;
+ int expires_in;
EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
- &url_fetcher, &at));
+ &url_fetcher, &at, &expires_in));
EXPECT_TRUE(at.empty());
}
{ // Valid json: access token missing.
@@ -213,8 +216,9 @@ TEST_F(OAuth2AccessTokenFetcherTest, MAYBE_ParseGetAccessTokenResponse) {
url_fetcher.SetResponseString(kTokenResponseNoAccessToken);
std::string at;
+ int expires_in;
EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
- &url_fetcher, &at));
+ &url_fetcher, &at, &expires_in));
EXPECT_TRUE(at.empty());
}
{ // Valid json: all good.
@@ -222,8 +226,10 @@ TEST_F(OAuth2AccessTokenFetcherTest, MAYBE_ParseGetAccessTokenResponse) {
url_fetcher.SetResponseString(kValidTokenResponse);
std::string at;
+ int expires_in;
EXPECT_TRUE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
- &url_fetcher, &at));
+ &url_fetcher, &at, &expires_in));
EXPECT_EQ("at1", at);
+ EXPECT_EQ(3600, expires_in);
}
}
diff --git a/chrome/common/net/gaia/oauth2_api_call_flow.cc b/chrome/common/net/gaia/oauth2_api_call_flow.cc
index 6426d7e..4d43e51 100644
--- a/chrome/common/net/gaia/oauth2_api_call_flow.cc
+++ b/chrome/common/net/gaia/oauth2_api_call_flow.cc
@@ -135,7 +135,8 @@ void OAuth2ApiCallFlow::OnURLFetchComplete(const net::URLFetcher* source) {
EndApiCall(source);
}
-void OAuth2ApiCallFlow::OnGetTokenSuccess(const std::string& access_token) {
+void OAuth2ApiCallFlow::OnGetTokenSuccess(const std::string& access_token,
+ const base::Time& expiration_time) {
access_token_ = access_token;
EndMintAccessToken(NULL);
}
diff --git a/chrome/common/net/gaia/oauth2_api_call_flow.h b/chrome/common/net/gaia/oauth2_api_call_flow.h
index 6db2cba..c53aa45 100644
--- a/chrome/common/net/gaia/oauth2_api_call_flow.h
+++ b/chrome/common/net/gaia/oauth2_api_call_flow.h
@@ -53,7 +53,8 @@ class OAuth2ApiCallFlow
virtual void Start();
// OAuth2AccessTokenFetcher implementation.
- virtual void OnGetTokenSuccess(const std::string& access_token) OVERRIDE;
+ virtual void OnGetTokenSuccess(const std::string& access_token,
+ const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
// net::URLFetcherDelegate implementation.
diff --git a/chrome/common/net/gaia/oauth2_api_call_flow_unittest.cc b/chrome/common/net/gaia/oauth2_api_call_flow_unittest.cc
index 5df058a..b042f3b 100644
--- a/chrome/common/net/gaia/oauth2_api_call_flow_unittest.cc
+++ b/chrome/common/net/gaia/oauth2_api_call_flow_unittest.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "base/memory/scoped_ptr.h"
+#include "base/time.h"
#include "chrome/common/net/gaia/gaia_urls.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/net/gaia/oauth2_access_token_consumer.h"
@@ -194,7 +195,9 @@ TEST_F(OAuth2ApiCallFlowTest, SecondApiCallSucceeds) {
flow_->OnURLFetchComplete(url_fetcher1);
TestURLFetcher* url_fetcher2 = SetupApiCall(true, net::HTTP_OK);
EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher2));
- flow_->OnGetTokenSuccess(at);
+ flow_->OnGetTokenSuccess(
+ at,
+ base::Time::Now() + base::TimeDelta::FromMinutes(3600));
flow_->OnURLFetchComplete(url_fetcher2);
}
@@ -210,7 +213,9 @@ TEST_F(OAuth2ApiCallFlowTest, SecondApiCallFails) {
flow_->OnURLFetchComplete(url_fetcher1);
TestURLFetcher* url_fetcher2 = SetupApiCall(false, net::HTTP_UNAUTHORIZED);
EXPECT_CALL(*flow_, ProcessApiCallFailure(url_fetcher2));
- flow_->OnGetTokenSuccess(at);
+ flow_->OnGetTokenSuccess(
+ at,
+ base::Time::Now() + base::TimeDelta::FromMinutes(3600));
flow_->OnURLFetchComplete(url_fetcher2);
}
@@ -240,7 +245,9 @@ TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenFirstApiCallSucceeds) {
TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_OK);
EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher));
flow_->Start();
- flow_->OnGetTokenSuccess(at);
+ flow_->OnGetTokenSuccess(
+ at,
+ base::Time::Now() + base::TimeDelta::FromMinutes(3600));
flow_->OnURLFetchComplete(url_fetcher);
}
@@ -254,7 +261,9 @@ TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenApiCallFails) {
TestURLFetcher* url_fetcher = SetupApiCall(false, net::HTTP_BAD_GATEWAY);
EXPECT_CALL(*flow_, ProcessApiCallFailure(url_fetcher));
flow_->Start();
- flow_->OnGetTokenSuccess(at);
+ flow_->OnGetTokenSuccess(
+ at,
+ base::Time::Now() + base::TimeDelta::FromMinutes(3600));
flow_->OnURLFetchComplete(url_fetcher);
}