1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/memory/scoped_ptr.h"
7 #include "base/strings/stringprintf.h"
8 #include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
9 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "content/public/test/test_browser_thread_bundle.h"
12 #include "google_apis/gaia/gaia_constants.h"
13 #include "google_apis/gaia/gaia_oauth_client.h"
14 #include "google_apis/gaia/gaia_urls.h"
15 #include "google_apis/gaia/google_service_auth_error.h"
16 #include "google_apis/gaia/oauth2_token_service.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/url_util.h"
19 #include "net/http/http_request_headers.h"
20 #include "net/http/http_status_code.h"
21 #include "net/url_request/test_url_fetcher_factory.h"
22 #include "net/url_request/url_fetcher_delegate.h"
23 #include "testing/gtest/include/gtest/gtest.h"
27 const char kAccountId
[] = "account_id";
28 const char kDeviceName
[] = "Compy";
29 const char kManagedUserId
[] = "abcdef";
31 const char kAccessToken
[] = "accesstoken";
32 const char kAuthorizationCode
[] = "authorizationcode";
33 const char kManagedUserToken
[] = "managedusertoken";
34 const char kOAuth2RefreshToken
[] = "refreshtoken";
36 const char kIssueTokenResponseFormat
[] =
41 const char kGetRefreshTokenResponseFormat
[] =
43 " \"access_token\": \"<ignored>\","
44 " \"expires_in\": 12345,"
45 " \"refresh_token\": \"%s\""
48 // Utility methods --------------------------------------------------
50 // Slightly hacky way to extract a value from a URL-encoded POST request body.
51 bool GetValueForKey(const std::string
& encoded_string
,
52 const std::string
& key
,
54 GURL
url("http://example.com/?" + encoded_string
);
55 return net::GetValueForKeyInQuery(url
, key
, value
);
58 void SendResponse(net::TestURLFetcher
* url_fetcher
,
59 const std::string
& response
) {
60 url_fetcher
->set_status(
61 net::URLRequestStatus(net::URLRequestStatus::SUCCESS
, 0));
62 url_fetcher
->set_response_code(net::HTTP_OK
);
63 url_fetcher
->SetResponseString(response
);
64 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
67 void SetNetworkError(net::TestURLFetcher
* url_fetcher
, int error
) {
68 url_fetcher
->set_status(
69 net::URLRequestStatus(net::URLRequestStatus::FAILED
, error
));
70 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
73 void SetHttpError(net::TestURLFetcher
* url_fetcher
, int error
) {
74 url_fetcher
->set_status(net::URLRequestStatus());
75 url_fetcher
->set_response_code(error
);
76 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
79 void VerifyTokenRequest(
80 std::vector
<FakeProfileOAuth2TokenService::PendingRequest
> requests
) {
81 ASSERT_EQ(1u, requests
.size());
82 EXPECT_EQ(1u, requests
[0].scopes
.size());
83 EXPECT_EQ(1u, requests
[0].scopes
.count(GaiaConstants::kOAuth1LoginScope
));
88 class ManagedUserRefreshTokenFetcherTest
: public testing::Test
{
90 ManagedUserRefreshTokenFetcherTest();
91 virtual ~ManagedUserRefreshTokenFetcherTest() {}
96 net::TestURLFetcher
* GetIssueTokenRequest();
97 net::TestURLFetcher
* GetRefreshTokenRequest();
99 void MakeOAuth2TokenServiceRequestSucceed();
100 void MakeOAuth2TokenServiceRequestFail(GoogleServiceAuthError::State error
);
101 void MakeIssueTokenRequestSucceed();
102 void MakeRefreshTokenFetchSucceed();
106 const GoogleServiceAuthError
& error() const { return error_
; }
107 const std::string
& token() const { return token_
; }
110 void OnTokenFetched(const GoogleServiceAuthError
& error
,
111 const std::string
& token
);
113 content::TestBrowserThreadBundle thread_bundle_
;
114 TestingProfile profile_
;
115 FakeProfileOAuth2TokenService oauth2_token_service_
;
116 net::TestURLFetcherFactory url_fetcher_factory_
;
117 scoped_ptr
<ManagedUserRefreshTokenFetcher
> token_fetcher_
;
119 GoogleServiceAuthError error_
;
121 base::WeakPtrFactory
<ManagedUserRefreshTokenFetcherTest
> weak_ptr_factory_
;
124 ManagedUserRefreshTokenFetcherTest::ManagedUserRefreshTokenFetcherTest()
126 ManagedUserRefreshTokenFetcher::Create(&oauth2_token_service_
,
128 profile_
.GetRequestContext())),
129 error_(GoogleServiceAuthError::NONE
),
130 weak_ptr_factory_(this) {}
132 void ManagedUserRefreshTokenFetcherTest::StartFetching() {
133 oauth2_token_service_
.IssueRefreshToken(kOAuth2RefreshToken
);
134 token_fetcher_
->Start(kManagedUserId
, kDeviceName
,
136 &ManagedUserRefreshTokenFetcherTest::OnTokenFetched
,
137 weak_ptr_factory_
.GetWeakPtr()));
141 ManagedUserRefreshTokenFetcherTest::GetIssueTokenRequest() {
142 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory_
.GetFetcherByID(1);
146 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
147 url_fetcher
->GetOriginalURL());
148 std::string access_token
;
149 net::HttpRequestHeaders headers
;
150 url_fetcher
->GetExtraRequestHeaders(&headers
);
151 EXPECT_TRUE(headers
.GetHeader("Authorization", &access_token
));
152 EXPECT_EQ(std::string("Bearer ") + kAccessToken
, access_token
);
153 const std::string upload_data
= url_fetcher
->upload_data();
154 std::string managed_user_id
;
155 EXPECT_TRUE(GetValueForKey(upload_data
, "profile_id", &managed_user_id
));
156 EXPECT_EQ(kManagedUserId
, managed_user_id
);
157 std::string device_name
;
158 EXPECT_TRUE(GetValueForKey(upload_data
, "device_name", &device_name
));
159 EXPECT_EQ(kDeviceName
, device_name
);
164 ManagedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() {
165 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory_
.GetFetcherByID(
166 gaia::GaiaOAuthClient::kUrlFetcherId
);
170 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
171 url_fetcher
->GetOriginalURL());
172 std::string auth_code
;
173 EXPECT_TRUE(GetValueForKey(url_fetcher
->upload_data(), "code", &auth_code
));
174 EXPECT_EQ(kAuthorizationCode
, auth_code
);
179 ManagedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestSucceed() {
180 std::vector
<FakeProfileOAuth2TokenService::PendingRequest
> requests
=
181 oauth2_token_service_
.GetPendingRequests();
182 VerifyTokenRequest(requests
);
183 base::Time expiration_date
= base::Time::Now() +
184 base::TimeDelta::FromHours(1);
185 oauth2_token_service_
.IssueTokenForScope(requests
[0].scopes
,
191 ManagedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestFail(
192 GoogleServiceAuthError::State error
) {
193 std::vector
<FakeProfileOAuth2TokenService::PendingRequest
> requests
=
194 oauth2_token_service_
.GetPendingRequests();
195 VerifyTokenRequest(requests
);
196 oauth2_token_service_
.IssueErrorForScope(requests
[0].scopes
,
197 GoogleServiceAuthError(error
));
200 void ManagedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() {
201 SendResponse(GetIssueTokenRequest(),
202 base::StringPrintf(kIssueTokenResponseFormat
,
203 kAuthorizationCode
));
206 void ManagedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
207 SendResponse(GetRefreshTokenRequest(),
208 base::StringPrintf(kGetRefreshTokenResponseFormat
,
212 void ManagedUserRefreshTokenFetcherTest::Reset() {
213 token_fetcher_
.reset();
216 void ManagedUserRefreshTokenFetcherTest::OnTokenFetched(
217 const GoogleServiceAuthError
& error
,
218 const std::string
& token
) {
223 // Tests --------------------------------------------------------
225 TEST_F(ManagedUserRefreshTokenFetcherTest
, Success
) {
227 MakeOAuth2TokenServiceRequestSucceed();
228 MakeIssueTokenRequestSucceed();
229 MakeRefreshTokenFetchSucceed();
231 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
232 EXPECT_EQ(kManagedUserToken
, token());
235 TEST_F(ManagedUserRefreshTokenFetcherTest
, ExpiredAccessToken
) {
237 MakeOAuth2TokenServiceRequestSucceed();
238 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED
);
239 MakeOAuth2TokenServiceRequestSucceed();
240 MakeIssueTokenRequestSucceed();
241 MakeRefreshTokenFetchSucceed();
243 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
244 EXPECT_EQ(kManagedUserToken
, token());
247 TEST_F(ManagedUserRefreshTokenFetcherTest
, ExpiredAccessTokenRetry
) {
248 // If we get a 401 error for the second time, we should give up instead of
251 MakeOAuth2TokenServiceRequestSucceed();
252 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED
);
253 MakeOAuth2TokenServiceRequestSucceed();
254 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED
);
256 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED
, error().state());
257 EXPECT_EQ(net::ERR_FAILED
, error().network_error());
258 EXPECT_EQ(std::string(), token());
261 TEST_F(ManagedUserRefreshTokenFetcherTest
, MalformedIssueTokenResponse
) {
263 MakeOAuth2TokenServiceRequestSucceed();
264 SendResponse(GetIssueTokenRequest(), "choke");
266 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED
, error().state());
267 EXPECT_EQ(net::ERR_INVALID_RESPONSE
, error().network_error());
268 EXPECT_EQ(std::string(), token());
271 TEST_F(ManagedUserRefreshTokenFetcherTest
, FetchAccessTokenFailure
) {
273 MakeOAuth2TokenServiceRequestFail(
274 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
);
276 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
, error().state());
277 EXPECT_EQ(std::string(), token());
280 TEST_F(ManagedUserRefreshTokenFetcherTest
, IssueTokenNetworkError
) {
282 MakeOAuth2TokenServiceRequestSucceed();
283 SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR
);
285 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED
, error().state());
286 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR
, error().network_error());
287 EXPECT_EQ(std::string(), token());
290 TEST_F(ManagedUserRefreshTokenFetcherTest
, FetchRefreshTokenNetworkError
) {
292 MakeOAuth2TokenServiceRequestSucceed();
293 MakeIssueTokenRequestSucceed();
294 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED
);
295 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
296 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED
);
298 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED
, error().state());
299 EXPECT_EQ(net::ERR_FAILED
, error().network_error());
300 EXPECT_EQ(std::string(), token());
303 TEST_F(ManagedUserRefreshTokenFetcherTest
,
304 FetchRefreshTokenTransientNetworkError
) {
306 MakeOAuth2TokenServiceRequestSucceed();
307 MakeIssueTokenRequestSucceed();
308 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED
);
310 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
311 MakeRefreshTokenFetchSucceed();
313 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
314 EXPECT_EQ(kManagedUserToken
, token());
317 TEST_F(ManagedUserRefreshTokenFetcherTest
, FetchRefreshTokenBadRequest
) {
319 MakeOAuth2TokenServiceRequestSucceed();
320 MakeIssueTokenRequestSucceed();
321 SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST
);
323 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED
, error().state());
324 EXPECT_EQ(net::ERR_FAILED
, error().network_error());
325 EXPECT_EQ(std::string(), token());
328 TEST_F(ManagedUserRefreshTokenFetcherTest
, CancelWhileFetchingAccessToken
) {
332 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
333 EXPECT_EQ(std::string(), token());
336 TEST_F(ManagedUserRefreshTokenFetcherTest
, CancelWhileCallingIssueToken
) {
338 MakeOAuth2TokenServiceRequestSucceed();
341 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
342 EXPECT_EQ(std::string(), token());
345 TEST_F(ManagedUserRefreshTokenFetcherTest
, CancelWhileFetchingRefreshToken
) {
347 MakeOAuth2TokenServiceRequestSucceed();
348 MakeIssueTokenRequestSucceed();
351 EXPECT_EQ(GoogleServiceAuthError::NONE
, error().state());
352 EXPECT_EQ(std::string(), token());