OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "base/bind.h" | |
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" | |
24 | |
25 namespace { | |
26 | |
27 const char kAccountId[] = "account_id"; | |
28 const char kDeviceName[] = "Compy"; | |
29 const char kManagedUserId[] = "abcdef"; | |
30 | |
31 const char kAccessToken[] = "accesstoken"; | |
32 const char kAuthorizationCode[] = "authorizationcode"; | |
33 const char kManagedUserToken[] = "managedusertoken"; | |
34 const char kOAuth2RefreshToken[] = "refreshtoken"; | |
35 | |
36 const char kIssueTokenResponseFormat[] = | |
37 "{" | |
38 " \"code\": \"%s\"" | |
39 "}"; | |
40 | |
41 const char kGetRefreshTokenResponseFormat[] = | |
42 "{" | |
43 " \"access_token\": \"<ignored>\"," | |
44 " \"expires_in\": 12345," | |
45 " \"refresh_token\": \"%s\"" | |
46 "}"; | |
47 | |
48 // Utility methods -------------------------------------------------- | |
49 | |
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, | |
53 std::string* value) { | |
54 GURL url("http://example.com/?" + encoded_string); | |
55 return net::GetValueForKeyInQuery(url, key, value); | |
56 } | |
57 | |
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); | |
65 } | |
66 | |
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); | |
71 } | |
72 | |
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); | |
77 } | |
78 | |
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)); | |
84 } | |
85 | |
86 } // namespace | |
87 | |
88 class ManagedUserRefreshTokenFetcherTest : public testing::Test { | |
89 public: | |
90 ManagedUserRefreshTokenFetcherTest(); | |
91 virtual ~ManagedUserRefreshTokenFetcherTest() {} | |
92 | |
93 protected: | |
94 void StartFetching(); | |
95 | |
96 net::TestURLFetcher* GetIssueTokenRequest(); | |
97 net::TestURLFetcher* GetRefreshTokenRequest(); | |
98 | |
99 void MakeOAuth2TokenServiceRequestSucceed(); | |
100 void MakeOAuth2TokenServiceRequestFail(GoogleServiceAuthError::State error); | |
101 void MakeIssueTokenRequestSucceed(); | |
102 void MakeRefreshTokenFetchSucceed(); | |
103 | |
104 void Reset(); | |
105 | |
106 const GoogleServiceAuthError& error() const { return error_; } | |
107 const std::string& token() const { return token_; } | |
108 | |
109 private: | |
110 void OnTokenFetched(const GoogleServiceAuthError& error, | |
111 const std::string& token); | |
112 | |
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_; | |
118 | |
119 GoogleServiceAuthError error_; | |
120 std::string token_; | |
121 base::WeakPtrFactory<ManagedUserRefreshTokenFetcherTest> weak_ptr_factory_; | |
122 }; | |
123 | |
124 ManagedUserRefreshTokenFetcherTest::ManagedUserRefreshTokenFetcherTest() | |
125 : token_fetcher_( | |
126 ManagedUserRefreshTokenFetcher::Create(&oauth2_token_service_, | |
127 kAccountId, | |
128 profile_.GetRequestContext())), | |
129 error_(GoogleServiceAuthError::NONE), | |
130 weak_ptr_factory_(this) {} | |
131 | |
132 void ManagedUserRefreshTokenFetcherTest::StartFetching() { | |
133 oauth2_token_service_.IssueRefreshToken(kOAuth2RefreshToken); | |
134 token_fetcher_->Start(kManagedUserId, kDeviceName, | |
135 base::Bind( | |
136 &ManagedUserRefreshTokenFetcherTest::OnTokenFetched, | |
137 weak_ptr_factory_.GetWeakPtr())); | |
138 } | |
139 | |
140 net::TestURLFetcher* | |
141 ManagedUserRefreshTokenFetcherTest::GetIssueTokenRequest() { | |
142 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1); | |
143 if (!url_fetcher) | |
144 return NULL; | |
145 | |
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); | |
160 return url_fetcher; | |
161 } | |
162 | |
163 net::TestURLFetcher* | |
164 ManagedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() { | |
165 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID( | |
166 gaia::GaiaOAuthClient::kUrlFetcherId); | |
167 if (!url_fetcher) | |
168 return NULL; | |
169 | |
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); | |
175 return url_fetcher; | |
176 } | |
177 | |
178 void | |
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, | |
186 kAccessToken, | |
187 expiration_date); | |
188 } | |
189 | |
190 void | |
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)); | |
198 } | |
199 | |
200 void ManagedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() { | |
201 SendResponse(GetIssueTokenRequest(), | |
202 base::StringPrintf(kIssueTokenResponseFormat, | |
203 kAuthorizationCode)); | |
204 } | |
205 | |
206 void ManagedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() { | |
207 SendResponse(GetRefreshTokenRequest(), | |
208 base::StringPrintf(kGetRefreshTokenResponseFormat, | |
209 kManagedUserToken)); | |
210 } | |
211 | |
212 void ManagedUserRefreshTokenFetcherTest::Reset() { | |
213 token_fetcher_.reset(); | |
214 } | |
215 | |
216 void ManagedUserRefreshTokenFetcherTest::OnTokenFetched( | |
217 const GoogleServiceAuthError& error, | |
218 const std::string& token) { | |
219 error_ = error; | |
220 token_ = token; | |
221 } | |
222 | |
223 // Tests -------------------------------------------------------- | |
224 | |
225 TEST_F(ManagedUserRefreshTokenFetcherTest, Success) { | |
226 StartFetching(); | |
227 MakeOAuth2TokenServiceRequestSucceed(); | |
228 MakeIssueTokenRequestSucceed(); | |
229 MakeRefreshTokenFetchSucceed(); | |
230 | |
231 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
232 EXPECT_EQ(kManagedUserToken, token()); | |
233 } | |
234 | |
235 TEST_F(ManagedUserRefreshTokenFetcherTest, ExpiredAccessToken) { | |
236 StartFetching(); | |
237 MakeOAuth2TokenServiceRequestSucceed(); | |
238 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED); | |
239 MakeOAuth2TokenServiceRequestSucceed(); | |
240 MakeIssueTokenRequestSucceed(); | |
241 MakeRefreshTokenFetchSucceed(); | |
242 | |
243 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
244 EXPECT_EQ(kManagedUserToken, token()); | |
245 } | |
246 | |
247 TEST_F(ManagedUserRefreshTokenFetcherTest, ExpiredAccessTokenRetry) { | |
248 // If we get a 401 error for the second time, we should give up instead of | |
249 // retrying again. | |
250 StartFetching(); | |
251 MakeOAuth2TokenServiceRequestSucceed(); | |
252 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED); | |
253 MakeOAuth2TokenServiceRequestSucceed(); | |
254 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED); | |
255 | |
256 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state()); | |
257 EXPECT_EQ(net::ERR_FAILED, error().network_error()); | |
258 EXPECT_EQ(std::string(), token()); | |
259 } | |
260 | |
261 TEST_F(ManagedUserRefreshTokenFetcherTest, MalformedIssueTokenResponse) { | |
262 StartFetching(); | |
263 MakeOAuth2TokenServiceRequestSucceed(); | |
264 SendResponse(GetIssueTokenRequest(), "choke"); | |
265 | |
266 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state()); | |
267 EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error()); | |
268 EXPECT_EQ(std::string(), token()); | |
269 } | |
270 | |
271 TEST_F(ManagedUserRefreshTokenFetcherTest, FetchAccessTokenFailure) { | |
272 StartFetching(); | |
273 MakeOAuth2TokenServiceRequestFail( | |
274 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
275 | |
276 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state()); | |
277 EXPECT_EQ(std::string(), token()); | |
278 } | |
279 | |
280 TEST_F(ManagedUserRefreshTokenFetcherTest, IssueTokenNetworkError) { | |
281 StartFetching(); | |
282 MakeOAuth2TokenServiceRequestSucceed(); | |
283 SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR); | |
284 | |
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()); | |
288 } | |
289 | |
290 TEST_F(ManagedUserRefreshTokenFetcherTest, FetchRefreshTokenNetworkError) { | |
291 StartFetching(); | |
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); | |
297 | |
298 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state()); | |
299 EXPECT_EQ(net::ERR_FAILED, error().network_error()); | |
300 EXPECT_EQ(std::string(), token()); | |
301 } | |
302 | |
303 TEST_F(ManagedUserRefreshTokenFetcherTest, | |
304 FetchRefreshTokenTransientNetworkError) { | |
305 StartFetching(); | |
306 MakeOAuth2TokenServiceRequestSucceed(); | |
307 MakeIssueTokenRequestSucceed(); | |
308 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED); | |
309 | |
310 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
311 MakeRefreshTokenFetchSucceed(); | |
312 | |
313 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
314 EXPECT_EQ(kManagedUserToken, token()); | |
315 } | |
316 | |
317 TEST_F(ManagedUserRefreshTokenFetcherTest, FetchRefreshTokenBadRequest) { | |
318 StartFetching(); | |
319 MakeOAuth2TokenServiceRequestSucceed(); | |
320 MakeIssueTokenRequestSucceed(); | |
321 SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST); | |
322 | |
323 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state()); | |
324 EXPECT_EQ(net::ERR_FAILED, error().network_error()); | |
325 EXPECT_EQ(std::string(), token()); | |
326 } | |
327 | |
328 TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileFetchingAccessToken) { | |
329 StartFetching(); | |
330 Reset(); | |
331 | |
332 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
333 EXPECT_EQ(std::string(), token()); | |
334 } | |
335 | |
336 TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileCallingIssueToken) { | |
337 StartFetching(); | |
338 MakeOAuth2TokenServiceRequestSucceed(); | |
339 Reset(); | |
340 | |
341 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
342 EXPECT_EQ(std::string(), token()); | |
343 } | |
344 | |
345 TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileFetchingRefreshToken) { | |
346 StartFetching(); | |
347 MakeOAuth2TokenServiceRequestSucceed(); | |
348 MakeIssueTokenRequestSucceed(); | |
349 Reset(); | |
350 | |
351 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state()); | |
352 EXPECT_EQ(std::string(), token()); | |
353 } | |
OLD | NEW |