Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: chrome/browser/managed_mode/managed_user_token_fetcher_unittest.cc

Issue 15977002: Add ManagedUserTokenFetcher to fetch scoped-down tokens. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/message_loop.h"
8 #include "base/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/managed_mode/managed_user_token_fetcher.h"
11 #include "chrome/browser/signin/oauth2_token_service.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "content/public/test/test_browser_thread.h"
14 #include "google_apis/gaia/gaia_urls.h"
15 #include "google_apis/gaia/google_service_auth_error.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/url_util.h"
18 #include "net/http/http_request_headers.h"
19 #include "net/http/http_status_code.h"
20 #include "net/url_request/test_url_fetcher_factory.h"
21 #include "net/url_request/url_fetcher_delegate.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace {
25
26 const char kManagedUserId[] = "abcdef";
27 const char kName[] = "Homestar";
28 const char kDeviceName[] = "Compy";
29
30 const char kAccessToken[] = "accesstoken";
31 const char kAuthorizationCode[] = "authorizationcode";
32 const char kManagedUserToken[] = "managedusertoken";
33
34 const char kIssueTokenResponseFormat[] =
35 "{"
36 " \"code\": \"%s\""
37 "}";
38
39 const char kGetRefreshTokenResponseFormat[] =
40 "{"
41 " \"access_token\": \"<ignored>\","
42 " \"expires_in\": 12345,"
43 " \"refresh_token\": \"%s\""
44 "}";
45
46 // MockOAuth2TokenService ---------------------------------------------
47
48 class MockOAuth2TokenService : public OAuth2TokenService {
49 public:
50 class Request : public OAuth2TokenService::Request {
51 public:
52 Request(const OAuth2TokenService::ScopeSet& scopes,
53 OAuth2TokenService::Consumer* consumer,
54 MockOAuth2TokenService* owner);
55 virtual ~Request();
56
57 void Succeed();
58 void Fail(GoogleServiceAuthError::State error);
59
60 const OAuth2TokenService::ScopeSet& scopes() const { return scopes_; }
61
62 private:
63 OAuth2TokenService::ScopeSet scopes_;
64
65 OAuth2TokenService::Consumer* consumer_;
66
67 MockOAuth2TokenService* owner_;
68 };
69
70 MockOAuth2TokenService();
71 virtual ~MockOAuth2TokenService();
72
73 Request* request() const { return request_; }
74
75 void ClearRequest(Request* request);
76
77 private:
78 // OAuth2TokenService overrides:
79 virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
80 const OAuth2TokenService::ScopeSet& scopes,
81 OAuth2TokenService::Consumer* consumer) OVERRIDE;
82 virtual std::string GetRefreshToken() OVERRIDE;
83
84 Request* request_;
85
86 DISALLOW_COPY_AND_ASSIGN(MockOAuth2TokenService);
87 };
88
89 MockOAuth2TokenService::Request::Request(
90 const OAuth2TokenService::ScopeSet& scopes,
91 OAuth2TokenService::Consumer* consumer,
92 MockOAuth2TokenService* owner)
93 : scopes_(scopes),
94 consumer_(consumer),
95 owner_(owner) {}
96
97 MockOAuth2TokenService::Request::~Request() {
98 owner_->ClearRequest(this);
99 }
100
101 void MockOAuth2TokenService::Request::Succeed() {
102 base::Time expiration_date = base::Time::Now() +
103 base::TimeDelta::FromHours(1);
104 consumer_->OnGetTokenSuccess(this, kAccessToken, expiration_date);
105 }
106
107 void MockOAuth2TokenService::Request::Fail(
108 GoogleServiceAuthError::State error) {
109 consumer_->OnGetTokenFailure(this, GoogleServiceAuthError(error));
110 }
111
112 MockOAuth2TokenService::MockOAuth2TokenService()
113 : OAuth2TokenService(NULL),
114 request_(NULL) {}
115
116 MockOAuth2TokenService::~MockOAuth2TokenService() {
117 EXPECT_FALSE(request_);
118 }
119
120 void MockOAuth2TokenService::ClearRequest(
121 MockOAuth2TokenService::Request* request) {
122 if (request_ == request)
123 request_ = NULL;
124 }
125
126 scoped_ptr<OAuth2TokenService::Request> MockOAuth2TokenService::StartRequest(
127 const OAuth2TokenService::ScopeSet& scopes,
128 OAuth2TokenService::Consumer* consumer) {
129 scoped_ptr<Request> request(new Request(scopes, consumer, this));
130 request_ = request.get();
131 return request.PassAs<OAuth2TokenService::Request>();
132 }
133
134 std::string MockOAuth2TokenService::GetRefreshToken() {
135 NOTREACHED();
136 return std::string();
137 }
138
139 // Utility methods --------------------------------------------------
140
141 // Slightly hacky way to extract a value from a URL-encoded POST request body.
142 bool GetValueForKey(const std::string& encoded_string,
143 const std::string& key,
144 std::string* value) {
145 GURL url("http://example.com/?" + encoded_string);
146 return net::GetValueForKeyInQuery(url, key, value);
147 }
148
149 void SendResponse(net::TestURLFetcher* url_fetcher,
150 const std::string& response) {
151 url_fetcher->set_status(
152 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
153 url_fetcher->set_response_code(net::HTTP_OK);
154 url_fetcher->SetResponseString(response);
155 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
156 }
157
158 void SetNetworkError(net::TestURLFetcher* url_fetcher, int error) {
159 url_fetcher->set_status(
160 net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
161 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
162 }
163
164 void SetHttpError(net::TestURLFetcher* url_fetcher, int error) {
165 url_fetcher->set_status(net::URLRequestStatus());
166 url_fetcher->set_response_code(error);
167 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
168 }
169
170 } // namespace
171
172 class ManagedUserTokenFetcherTest : public testing::Test {
173 public:
174 ManagedUserTokenFetcherTest();
175 virtual ~ManagedUserTokenFetcherTest() {}
176
177 protected:
178 void StartFetching();
179
180 MockOAuth2TokenService::Request* GetOAuth2TokenServiceRequest();
181 net::TestURLFetcher* GetIssueTokenRequest();
182 net::TestURLFetcher* GetRefreshTokenRequest();
183
184 void MakeIssueTokenRequestSucceed();
185 void MakeRefreshTokenFetchSucceed();
186
187 void Reset();
188
189 const GoogleServiceAuthError& error() const { return error_; }
190 const std::string& token() const { return token_; }
191
192 private:
193 void OnTokenFetched(const GoogleServiceAuthError& error,
194 const std::string& token);
195
196 base::WeakPtrFactory<ManagedUserTokenFetcherTest> weak_ptr_factory_;
197 base::MessageLoop message_loop_;
198 content::TestBrowserThread ui_thread_;
199 TestingProfile profile_;
200 MockOAuth2TokenService oauth2_token_service_;
201 net::TestURLFetcherFactory url_fetcher_factory_;
202 scoped_ptr<ManagedUserTokenFetcher> token_fetcher_;
203
204 GoogleServiceAuthError error_;
205 std::string token_;
206 };
207
208 ManagedUserTokenFetcherTest::ManagedUserTokenFetcherTest()
209 : weak_ptr_factory_(this),
210 ui_thread_(content::BrowserThread::UI, &message_loop_),
211 token_fetcher_(
212 ManagedUserTokenFetcher::Create(&oauth2_token_service_,
213 profile_.GetRequestContext())),
214 error_(GoogleServiceAuthError::NONE) {}
215
216 void ManagedUserTokenFetcherTest::StartFetching() {
217 token_fetcher_->Start(kManagedUserId, UTF8ToUTF16(kName), kDeviceName,
218 base::Bind(
219 &ManagedUserTokenFetcherTest::OnTokenFetched,
220 weak_ptr_factory_.GetWeakPtr()));
221 }
222
223 MockOAuth2TokenService::Request*
224 ManagedUserTokenFetcherTest::GetOAuth2TokenServiceRequest() {
225 MockOAuth2TokenService::Request* request = oauth2_token_service_.request();
226 EXPECT_EQ(0u, request->scopes().size());
227 return request;
228 }
229
230 net::TestURLFetcher* ManagedUserTokenFetcherTest::GetIssueTokenRequest() {
231 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1);
232 if (!url_fetcher)
233 return NULL;
234
235 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
236 url_fetcher->GetOriginalURL().spec());
237 std::string access_token;
238 net::HttpRequestHeaders headers;
239 url_fetcher->GetExtraRequestHeaders(&headers);
240 EXPECT_TRUE(headers.GetHeader("Authorization", &access_token));
241 EXPECT_EQ(std::string("Bearer ") + kAccessToken, access_token);
242 const std::string upload_data = url_fetcher->upload_data();
243 std::string managed_user_id;
244 EXPECT_TRUE(GetValueForKey(upload_data, "profile_id", &managed_user_id));
245 EXPECT_EQ(kManagedUserId, managed_user_id);
246 std::string name;
247 EXPECT_TRUE(GetValueForKey(upload_data, "profile_name", &name));
248 EXPECT_EQ(kName, name);
249 std::string device_name;
250 EXPECT_TRUE(GetValueForKey(upload_data, "device_name", &device_name));
251 EXPECT_EQ(kDeviceName, device_name);
252 return url_fetcher;
253 }
254
255 net::TestURLFetcher* ManagedUserTokenFetcherTest::GetRefreshTokenRequest() {
256 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0);
257 if (!url_fetcher)
258 return NULL;
259
260 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
261 url_fetcher->GetOriginalURL().spec());
262 std::string auth_code;
263 EXPECT_TRUE(GetValueForKey(url_fetcher->upload_data(), "code", &auth_code));
264 EXPECT_EQ(kAuthorizationCode, auth_code);
265 return url_fetcher;
266 }
267
268 void ManagedUserTokenFetcherTest::MakeIssueTokenRequestSucceed() {
269 SendResponse(GetIssueTokenRequest(),
270 base::StringPrintf(kIssueTokenResponseFormat,
271 kAuthorizationCode));
272 }
273
274 void ManagedUserTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
275 SendResponse(GetRefreshTokenRequest(),
276 base::StringPrintf(kGetRefreshTokenResponseFormat,
277 kManagedUserToken));
278 }
279
280 void ManagedUserTokenFetcherTest::Reset() {
281 token_fetcher_.reset();
282 }
283
284 void ManagedUserTokenFetcherTest::OnTokenFetched(
285 const GoogleServiceAuthError& error,
286 const std::string& token) {
287 error_ = error;
288 token_ = token;
289 }
290
291 // Tests --------------------------------------------------------
292
293 TEST_F(ManagedUserTokenFetcherTest, Success) {
294 StartFetching();
295 GetOAuth2TokenServiceRequest()->Succeed();
296 MakeIssueTokenRequestSucceed();
297 MakeRefreshTokenFetchSucceed();
298
299 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
300 EXPECT_EQ(kManagedUserToken, token());
301 }
302
303 TEST_F(ManagedUserTokenFetcherTest, ExpiredAccessToken) {
304 StartFetching();
305 GetOAuth2TokenServiceRequest()->Succeed();
306 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
307 MakeIssueTokenRequestSucceed();
308 GetOAuth2TokenServiceRequest()->Succeed();
309 MakeRefreshTokenFetchSucceed();
310
311 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
312 EXPECT_EQ(kManagedUserToken, token());
313 }
314
315 TEST_F(ManagedUserTokenFetcherTest, MalformedIssueTokenResponse) {
316 StartFetching();
317 GetOAuth2TokenServiceRequest()->Succeed();
318 SendResponse(GetIssueTokenRequest(), "choke");
319
320 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
321 EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error());
322 EXPECT_EQ(std::string(), token());
323 }
324
325 TEST_F(ManagedUserTokenFetcherTest, FetchAccessTokenFailure) {
326 StartFetching();
327 GetOAuth2TokenServiceRequest()->Fail(
328 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
329
330 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state());
331 EXPECT_EQ(std::string(), token());
332 }
333
334 TEST_F(ManagedUserTokenFetcherTest, IssueTokenNetworkError) {
335 StartFetching();
336 GetOAuth2TokenServiceRequest()->Succeed();
337 SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR);
338
339 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
340 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, error().network_error());
341 EXPECT_EQ(std::string(), token());
342 }
343
344 TEST_F(ManagedUserTokenFetcherTest, FetchRefreshTokenNetworkError) {
345 StartFetching();
346 GetOAuth2TokenServiceRequest()->Succeed();
347 MakeIssueTokenRequestSucceed();
348 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
349 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
350 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
351
352 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
353 EXPECT_EQ(net::ERR_FAILED, error().network_error());
354 EXPECT_EQ(std::string(), token());
355 }
356
357 TEST_F(ManagedUserTokenFetcherTest, FetchRefreshTokenTransientNetworkError) {
358 StartFetching();
359 GetOAuth2TokenServiceRequest()->Succeed();
360 MakeIssueTokenRequestSucceed();
361 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
362
363 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
364 MakeRefreshTokenFetchSucceed();
365
366 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
367 EXPECT_EQ(kManagedUserToken, token());
368 }
369
370 TEST_F(ManagedUserTokenFetcherTest, FetchRefreshTokenBadRequest) {
371 StartFetching();
372 GetOAuth2TokenServiceRequest()->Succeed();
373 MakeIssueTokenRequestSucceed();
374 SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST);
375
376 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
377 EXPECT_EQ(net::ERR_FAILED, error().network_error());
378 EXPECT_EQ(std::string(), token());
379 }
380
381 TEST_F(ManagedUserTokenFetcherTest, CancelWhileFetchingAccessToken) {
382 StartFetching();
383 Reset();
384
385 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
386 EXPECT_EQ(std::string(), token());
387 }
388
389 TEST_F(ManagedUserTokenFetcherTest, CancelWhileCallingIssueToken) {
390 StartFetching();
391 GetOAuth2TokenServiceRequest()->Succeed();
392 Reset();
393
394 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
395 EXPECT_EQ(std::string(), token());
396 }
397
398 TEST_F(ManagedUserTokenFetcherTest, CancelWhileFetchingRefreshToken) {
399 StartFetching();
400 GetOAuth2TokenServiceRequest()->Succeed();
401 MakeIssueTokenRequestSucceed();
402 Reset();
403
404 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
405 EXPECT_EQ(std::string(), token());
406 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698