1 // Copyright 2014 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/signin/fake_profile_oauth2_token_service.h"
9 #include "chrome/browser/supervised_user/supervised_user_refresh_token_fetcher.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 kSupervisedUserId[] = "abcdef";
31 const char kAccessToken[] = "accesstoken";
32 const char kAuthorizationCode[] = "authorizationcode";
33 const char kSupervisedUserToken[] = "supervisedusertoken";
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 SupervisedUserRefreshTokenFetcherTest : public testing::Test {
90 SupervisedUserRefreshTokenFetcherTest();
91 virtual ~SupervisedUserRefreshTokenFetcherTest() {}
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<SupervisedUserRefreshTokenFetcher> token_fetcher_;
119 GoogleServiceAuthError error_;
121 base::WeakPtrFactory<SupervisedUserRefreshTokenFetcherTest> weak_ptr_factory_;
124 SupervisedUserRefreshTokenFetcherTest::SupervisedUserRefreshTokenFetcherTest()
125 : token_fetcher_(SupervisedUserRefreshTokenFetcher::Create(
126 &oauth2_token_service_,
128 profile_.GetRequestContext())),
129 error_(GoogleServiceAuthError::NONE),
130 weak_ptr_factory_(this) {}
132 void SupervisedUserRefreshTokenFetcherTest::StartFetching() {
133 oauth2_token_service_.IssueRefreshToken(kOAuth2RefreshToken);
134 token_fetcher_->Start(
138 &SupervisedUserRefreshTokenFetcherTest::OnTokenFetched,
139 weak_ptr_factory_.GetWeakPtr()));
143 SupervisedUserRefreshTokenFetcherTest::GetIssueTokenRequest() {
144 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1);
148 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
149 url_fetcher->GetOriginalURL());
150 std::string access_token;
151 net::HttpRequestHeaders headers;
152 url_fetcher->GetExtraRequestHeaders(&headers);
153 EXPECT_TRUE(headers.GetHeader("Authorization", &access_token));
154 EXPECT_EQ(std::string("Bearer ") + kAccessToken, access_token);
155 const std::string upload_data = url_fetcher->upload_data();
156 std::string supervised_user_id;
157 EXPECT_TRUE(GetValueForKey(upload_data, "profile_id", &supervised_user_id));
158 EXPECT_EQ(kSupervisedUserId, supervised_user_id);
159 std::string device_name;
160 EXPECT_TRUE(GetValueForKey(upload_data, "device_name", &device_name));
161 EXPECT_EQ(kDeviceName, device_name);
166 SupervisedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() {
167 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(
168 gaia::GaiaOAuthClient::kUrlFetcherId);
172 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
173 url_fetcher->GetOriginalURL());
174 std::string auth_code;
175 EXPECT_TRUE(GetValueForKey(url_fetcher->upload_data(), "code", &auth_code));
176 EXPECT_EQ(kAuthorizationCode, auth_code);
181 SupervisedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestSucceed() {
182 std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests =
183 oauth2_token_service_.GetPendingRequests();
184 VerifyTokenRequest(requests);
185 base::Time expiration_date = base::Time::Now() +
186 base::TimeDelta::FromHours(1);
187 oauth2_token_service_.IssueTokenForScope(requests[0].scopes,
193 SupervisedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestFail(
194 GoogleServiceAuthError::State error) {
195 std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests =
196 oauth2_token_service_.GetPendingRequests();
197 VerifyTokenRequest(requests);
198 oauth2_token_service_.IssueErrorForScope(requests[0].scopes,
199 GoogleServiceAuthError(error));
202 void SupervisedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() {
203 SendResponse(GetIssueTokenRequest(),
204 base::StringPrintf(kIssueTokenResponseFormat,
205 kAuthorizationCode));
208 void SupervisedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
209 SendResponse(GetRefreshTokenRequest(),
210 base::StringPrintf(kGetRefreshTokenResponseFormat,
211 kSupervisedUserToken));
214 void SupervisedUserRefreshTokenFetcherTest::Reset() {
215 token_fetcher_.reset();
218 void SupervisedUserRefreshTokenFetcherTest::OnTokenFetched(
219 const GoogleServiceAuthError& error,
220 const std::string& token) {
225 // Tests --------------------------------------------------------
227 TEST_F(SupervisedUserRefreshTokenFetcherTest, Success) {
229 MakeOAuth2TokenServiceRequestSucceed();
230 MakeIssueTokenRequestSucceed();
231 MakeRefreshTokenFetchSucceed();
233 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
234 EXPECT_EQ(kSupervisedUserToken, token());
237 TEST_F(SupervisedUserRefreshTokenFetcherTest, ExpiredAccessToken) {
239 MakeOAuth2TokenServiceRequestSucceed();
240 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
241 MakeOAuth2TokenServiceRequestSucceed();
242 MakeIssueTokenRequestSucceed();
243 MakeRefreshTokenFetchSucceed();
245 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
246 EXPECT_EQ(kSupervisedUserToken, token());
249 TEST_F(SupervisedUserRefreshTokenFetcherTest, ExpiredAccessTokenRetry) {
250 // If we get a 401 error for the second time, we should give up instead of
253 MakeOAuth2TokenServiceRequestSucceed();
254 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
255 MakeOAuth2TokenServiceRequestSucceed();
256 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
258 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
259 EXPECT_EQ(net::ERR_FAILED, error().network_error());
260 EXPECT_EQ(std::string(), token());
263 TEST_F(SupervisedUserRefreshTokenFetcherTest, MalformedIssueTokenResponse) {
265 MakeOAuth2TokenServiceRequestSucceed();
266 SendResponse(GetIssueTokenRequest(), "choke");
268 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
269 EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error());
270 EXPECT_EQ(std::string(), token());
273 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchAccessTokenFailure) {
275 MakeOAuth2TokenServiceRequestFail(
276 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
278 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state());
279 EXPECT_EQ(std::string(), token());
282 TEST_F(SupervisedUserRefreshTokenFetcherTest, IssueTokenNetworkError) {
284 MakeOAuth2TokenServiceRequestSucceed();
285 SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR);
287 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
288 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, error().network_error());
289 EXPECT_EQ(std::string(), token());
292 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchRefreshTokenNetworkError) {
294 MakeOAuth2TokenServiceRequestSucceed();
295 MakeIssueTokenRequestSucceed();
296 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
297 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
298 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
300 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
301 EXPECT_EQ(net::ERR_FAILED, error().network_error());
302 EXPECT_EQ(std::string(), token());
305 TEST_F(SupervisedUserRefreshTokenFetcherTest,
306 FetchRefreshTokenTransientNetworkError) {
308 MakeOAuth2TokenServiceRequestSucceed();
309 MakeIssueTokenRequestSucceed();
310 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
312 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
313 MakeRefreshTokenFetchSucceed();
315 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
316 EXPECT_EQ(kSupervisedUserToken, token());
319 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchRefreshTokenBadRequest) {
321 MakeOAuth2TokenServiceRequestSucceed();
322 MakeIssueTokenRequestSucceed();
323 SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST);
325 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
326 EXPECT_EQ(net::ERR_FAILED, error().network_error());
327 EXPECT_EQ(std::string(), token());
330 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileFetchingAccessToken) {
334 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
335 EXPECT_EQ(std::string(), token());
338 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileCallingIssueToken) {
340 MakeOAuth2TokenServiceRequestSucceed();
343 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
344 EXPECT_EQ(std::string(), token());
347 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileFetchingRefreshToken) {
349 MakeOAuth2TokenServiceRequestSucceed();
350 MakeIssueTokenRequestSucceed();
353 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
354 EXPECT_EQ(std::string(), token());