ipc: Remove use of MessageLoopProxy and deprecated MessageLoop APIs
[chromium-blink-merge.git] / google_apis / gaia / fake_gaia.cc
blobbf2331d970abd5c8fcf42bd09cb9f1262ea6ff2d
1 // Copyright (c) 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.
5 #include "google_apis/gaia/fake_gaia.h"
7 #include <vector>
9 #include "base/base_paths.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_writer.h"
15 #include "base/logging.h"
16 #include "base/memory/linked_ptr.h"
17 #include "base/path_service.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_split.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/values.h"
23 #include "google_apis/gaia/gaia_constants.h"
24 #include "google_apis/gaia/gaia_urls.h"
25 #include "net/base/url_util.h"
26 #include "net/cookies/parsed_cookie.h"
27 #include "net/http/http_status_code.h"
28 #include "net/test/embedded_test_server/http_request.h"
29 #include "net/test/embedded_test_server/http_response.h"
30 #include "url/url_parse.h"
32 #define REGISTER_RESPONSE_HANDLER(url, method) \
33 request_handlers_.insert(std::make_pair( \
34 url.path(), base::Bind(&FakeGaia::method, base::Unretained(this))))
36 #define REGISTER_PATH_RESPONSE_HANDLER(path, method) \
37 request_handlers_.insert(std::make_pair( \
38 path, base::Bind(&FakeGaia::method, base::Unretained(this))))
40 using namespace net::test_server;
42 namespace {
44 const char kTestAuthCode[] = "fake-auth-code";
45 const char kTestGaiaUberToken[] = "fake-uber-token";
46 const char kTestAuthLoginAccessToken[] = "fake-access-token";
47 const char kTestRefreshToken[] = "fake-refresh-token";
48 const char kTestSessionSIDCookie[] = "fake-session-SID-cookie";
49 const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie";
50 const char kTestOAuthLoginSID[] = "fake-oauth-SID-cookie";
51 const char kTestOAuthLoginLSID[] = "fake-oauth-LSID-cookie";
52 const char kTestOAuthLoginAuthCode[] = "fake-oauth-auth-code";
54 const char kDefaultGaiaId[] ="12345";
56 const base::FilePath::CharType kServiceLogin[] =
57 FILE_PATH_LITERAL("google_apis/test/service_login.html");
59 const base::FilePath::CharType kEmbeddedSetupChromeos[] =
60 FILE_PATH_LITERAL("google_apis/test/embedded_setup_chromeos.html");
62 // OAuth2 Authentication header value prefix.
63 const char kAuthHeaderBearer[] = "Bearer ";
64 const char kAuthHeaderOAuth[] = "OAuth ";
66 const char kListAccountsResponseFormat[] =
67 "[\"gaia.l.a.r\",[[\"gaia.l.a\",1,\"\",\"%s\",\"\",1,1,0]]]";
69 typedef std::map<std::string, std::string> CookieMap;
71 // Parses cookie name-value map our of |request|.
72 CookieMap GetRequestCookies(const HttpRequest& request) {
73 CookieMap result;
74 std::map<std::string, std::string>::const_iterator iter =
75 request.headers.find("Cookie");
76 if (iter != request.headers.end()) {
77 std::vector<std::string> cookie_nv_pairs;
78 base::SplitString(iter->second, ' ', &cookie_nv_pairs);
79 for(std::vector<std::string>::const_iterator cookie_line =
80 cookie_nv_pairs.begin();
81 cookie_line != cookie_nv_pairs.end();
82 ++cookie_line) {
83 std::vector<std::string> name_value;
84 base::SplitString(*cookie_line, '=', &name_value);
85 if (name_value.size() != 2)
86 continue;
88 std::string value = name_value[1];
89 if (value.size() && value[value.size() - 1] == ';')
90 value = value.substr(0, value.size() -1);
92 result.insert(std::make_pair(name_value[0], value));
95 return result;
98 // Extracts the |access_token| from authorization header of |request|.
99 bool GetAccessToken(const HttpRequest& request,
100 const char* auth_token_prefix,
101 std::string* access_token) {
102 std::map<std::string, std::string>::const_iterator auth_header_entry =
103 request.headers.find("Authorization");
104 if (auth_header_entry != request.headers.end()) {
105 if (StartsWithASCII(auth_header_entry->second, auth_token_prefix, true)) {
106 *access_token = auth_header_entry->second.substr(
107 strlen(auth_token_prefix));
108 return true;
112 return false;
115 void SetCookies(BasicHttpResponse* http_response,
116 const std::string& sid_cookie,
117 const std::string& lsid_cookie) {
118 http_response->AddCustomHeader(
119 "Set-Cookie",
120 base::StringPrintf("SID=%s; Path=/; HttpOnly", sid_cookie.c_str()));
121 http_response->AddCustomHeader(
122 "Set-Cookie",
123 base::StringPrintf("LSID=%s; Path=/; HttpOnly", lsid_cookie.c_str()));
126 } // namespace
128 FakeGaia::AccessTokenInfo::AccessTokenInfo()
129 : expires_in(3600) {}
131 FakeGaia::AccessTokenInfo::~AccessTokenInfo() {}
133 FakeGaia::MergeSessionParams::MergeSessionParams() {
136 FakeGaia::MergeSessionParams::~MergeSessionParams() {
139 FakeGaia::FakeGaia() : issue_oauth_code_cookie_(false) {
140 base::FilePath source_root_dir;
141 PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir);
142 CHECK(base::ReadFileToString(
143 source_root_dir.Append(base::FilePath(kServiceLogin)),
144 &service_login_response_));
145 CHECK(base::ReadFileToString(
146 source_root_dir.Append(base::FilePath(kEmbeddedSetupChromeos)),
147 &embedded_setup_chromeos_response_));
150 FakeGaia::~FakeGaia() {}
152 void FakeGaia::SetFakeMergeSessionParams(
153 const std::string& email,
154 const std::string& auth_sid_cookie,
155 const std::string& auth_lsid_cookie) {
156 FakeGaia::MergeSessionParams params;
157 params.auth_sid_cookie = auth_sid_cookie;
158 params.auth_lsid_cookie = auth_lsid_cookie;
159 params.auth_code = kTestAuthCode;
160 params.refresh_token = kTestRefreshToken;
161 params.access_token = kTestAuthLoginAccessToken;
162 params.gaia_uber_token = kTestGaiaUberToken;
163 params.session_sid_cookie = kTestSessionSIDCookie;
164 params.session_lsid_cookie = kTestSessionLSIDCookie;
165 params.email = email;
166 SetMergeSessionParams(params);
169 void FakeGaia::SetMergeSessionParams(
170 const MergeSessionParams& params) {
171 merge_session_params_ = params;
174 void FakeGaia::MapEmailToGaiaId(const std::string& email,
175 const std::string& gaia_id) {
176 DCHECK(!email.empty());
177 DCHECK(!gaia_id.empty());
178 email_to_gaia_id_map_[email] = gaia_id;
181 std::string FakeGaia::GetGaiaIdOfEmail(const std::string& email) const {
182 DCHECK(!email.empty());
183 auto it = email_to_gaia_id_map_.find(email);
184 return it == email_to_gaia_id_map_.end() ? std::string(kDefaultGaiaId) :
185 it->second;
188 void FakeGaia::AddGoogleAccountsSigninHeader(
189 net::test_server::BasicHttpResponse* http_response,
190 const std::string& email) const {
191 DCHECK(!email.empty());
192 http_response->AddCustomHeader("google-accounts-signin",
193 base::StringPrintf(
194 "email=\"%s\", obfuscatedid=\"%s\", sessionindex=0",
195 email.c_str(), GetGaiaIdOfEmail(email).c_str()));
198 void FakeGaia::SetOAuthCodeCookie(
199 net::test_server::BasicHttpResponse* http_response) const {
200 http_response->AddCustomHeader(
201 "Set-Cookie",
202 base::StringPrintf(
203 "oauth_code=%s; Path=/o/GetOAuth2Token; Secure; HttpOnly;",
204 merge_session_params_.auth_code.c_str()));
207 void FakeGaia::Initialize() {
208 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
209 // Handles /MergeSession GAIA call.
210 REGISTER_RESPONSE_HANDLER(
211 gaia_urls->merge_session_url(), HandleMergeSession);
213 // Handles /o/oauth2/programmatic_auth GAIA call.
214 REGISTER_RESPONSE_HANDLER(
215 gaia_urls->client_login_to_oauth2_url(), HandleProgramaticAuth);
217 // Handles /ServiceLogin GAIA call.
218 REGISTER_RESPONSE_HANDLER(
219 gaia_urls->service_login_url(), HandleServiceLogin);
221 // Handles /embedded/setup/chromeos GAIA call.
222 REGISTER_RESPONSE_HANDLER(gaia_urls->embedded_setup_chromeos_url(),
223 HandleEmbeddedSetupChromeos);
225 // Handles /OAuthLogin GAIA call.
226 REGISTER_RESPONSE_HANDLER(
227 gaia_urls->oauth1_login_url(), HandleOAuthLogin);
229 // Handles /ServiceLoginAuth GAIA call.
230 REGISTER_RESPONSE_HANDLER(
231 gaia_urls->service_login_auth_url(), HandleServiceLoginAuth);
233 // Handles /_/embedded/lookup/accountlookup for /embedded/setup/chromeos
234 // authentication request.
235 REGISTER_PATH_RESPONSE_HANDLER("/_/embedded/lookup/accountlookup",
236 HandleEmbeddedLookupAccountLookup);
238 // Handles /_/embedded/signin/challenge for /embedded/setup/chromeos
239 // authentication request.
240 REGISTER_PATH_RESPONSE_HANDLER("/_/embedded/signin/challenge",
241 HandleEmbeddedSigninChallenge);
243 // Handles /SSO GAIA call (not GAIA, made up for SAML tests).
244 REGISTER_PATH_RESPONSE_HANDLER("/SSO", HandleSSO);
246 // Handles /o/oauth2/token GAIA call.
247 REGISTER_RESPONSE_HANDLER(
248 gaia_urls->oauth2_token_url(), HandleAuthToken);
250 // Handles /oauth2/v2/tokeninfo GAIA call.
251 REGISTER_RESPONSE_HANDLER(
252 gaia_urls->oauth2_token_info_url(), HandleTokenInfo);
254 // Handles /oauth2/v2/IssueToken GAIA call.
255 REGISTER_RESPONSE_HANDLER(
256 gaia_urls->oauth2_issue_token_url(), HandleIssueToken);
258 // Handles /ListAccounts GAIA call.
259 REGISTER_RESPONSE_HANDLER(
260 gaia_urls->ListAccountsURLWithSource(std::string()), HandleListAccounts);
262 // Handles /GetUserInfo GAIA call.
263 REGISTER_RESPONSE_HANDLER(
264 gaia_urls->get_user_info_url(), HandleGetUserInfo);
266 // Handles /oauth2/v1/userinfo call.
267 REGISTER_RESPONSE_HANDLER(
268 gaia_urls->oauth_user_info_url(), HandleOAuthUserInfo);
271 scoped_ptr<HttpResponse> FakeGaia::HandleRequest(const HttpRequest& request) {
272 // The scheme and host of the URL is actually not important but required to
273 // get a valid GURL in order to parse |request.relative_url|.
274 GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
275 std::string request_path = request_url.path();
276 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
277 RequestHandlerMap::iterator iter = request_handlers_.find(request_path);
278 if (iter != request_handlers_.end()) {
279 LOG(WARNING) << "Serving request " << request_path;
280 iter->second.Run(request, http_response.get());
281 } else {
282 LOG(ERROR) << "Unhandled request " << request_path;
283 return scoped_ptr<HttpResponse>(); // Request not understood.
286 return http_response.Pass();
289 void FakeGaia::IssueOAuthToken(const std::string& auth_token,
290 const AccessTokenInfo& token_info) {
291 access_token_info_map_.insert(std::make_pair(auth_token, token_info));
294 void FakeGaia::RegisterSamlUser(const std::string& account_id,
295 const GURL& saml_idp) {
296 saml_account_idp_map_[account_id] = saml_idp;
299 // static
300 bool FakeGaia::GetQueryParameter(const std::string& query,
301 const std::string& key,
302 std::string* value) {
303 // Name and scheme actually don't matter, but are required to get a valid URL
304 // for parsing.
305 GURL query_url("http://localhost?" + query);
306 return net::GetValueForKeyInQuery(query_url, key, value);
309 void FakeGaia::HandleMergeSession(const HttpRequest& request,
310 BasicHttpResponse* http_response) {
311 http_response->set_code(net::HTTP_UNAUTHORIZED);
312 if (merge_session_params_.session_sid_cookie.empty() ||
313 merge_session_params_.session_lsid_cookie.empty()) {
314 http_response->set_code(net::HTTP_BAD_REQUEST);
315 return;
318 std::string uber_token;
319 if (!GetQueryParameter(request.content, "uberauth", &uber_token) ||
320 uber_token != merge_session_params_.gaia_uber_token) {
321 LOG(ERROR) << "Missing or invalid 'uberauth' param in /MergeSession call";
322 return;
325 std::string continue_url;
326 if (!GetQueryParameter(request.content, "continue", &continue_url)) {
327 LOG(ERROR) << "Missing or invalid 'continue' param in /MergeSession call";
328 return;
331 std::string source;
332 if (!GetQueryParameter(request.content, "source", &source)) {
333 LOG(ERROR) << "Missing or invalid 'source' param in /MergeSession call";
334 return;
337 SetCookies(http_response,
338 merge_session_params_.session_sid_cookie,
339 merge_session_params_.session_lsid_cookie);
340 // TODO(zelidrag): Not used now.
341 http_response->set_content("OK");
342 http_response->set_code(net::HTTP_OK);
345 void FakeGaia::HandleProgramaticAuth(
346 const HttpRequest& request,
347 BasicHttpResponse* http_response) {
348 http_response->set_code(net::HTTP_UNAUTHORIZED);
349 if (merge_session_params_.auth_code.empty()) {
350 http_response->set_code(net::HTTP_BAD_REQUEST);
351 return;
354 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
355 std::string scope;
356 if (!GetQueryParameter(request.content, "scope", &scope) ||
357 GaiaConstants::kOAuth1LoginScope != scope) {
358 return;
361 CookieMap cookies = GetRequestCookies(request);
362 CookieMap::const_iterator sid_iter = cookies.find("SID");
363 if (sid_iter == cookies.end() ||
364 sid_iter->second != merge_session_params_.auth_sid_cookie) {
365 LOG(ERROR) << "/o/oauth2/programmatic_auth missing SID cookie";
366 return;
368 CookieMap::const_iterator lsid_iter = cookies.find("LSID");
369 if (lsid_iter == cookies.end() ||
370 lsid_iter->second != merge_session_params_.auth_lsid_cookie) {
371 LOG(ERROR) << "/o/oauth2/programmatic_auth missing LSID cookie";
372 return;
375 std::string client_id;
376 if (!GetQueryParameter(request.content, "client_id", &client_id) ||
377 gaia_urls->oauth2_chrome_client_id() != client_id) {
378 return;
381 http_response->AddCustomHeader(
382 "Set-Cookie",
383 base::StringPrintf(
384 "oauth_code=%s; Path=/o/GetOAuth2Token; Secure; HttpOnly;",
385 merge_session_params_.auth_code.c_str()));
386 http_response->set_code(net::HTTP_OK);
387 http_response->set_content_type("text/html");
390 void FakeGaia::FormatJSONResponse(const base::DictionaryValue& response_dict,
391 BasicHttpResponse* http_response) {
392 std::string response_json;
393 base::JSONWriter::Write(&response_dict, &response_json);
394 http_response->set_content(response_json);
395 http_response->set_code(net::HTTP_OK);
398 const FakeGaia::AccessTokenInfo* FakeGaia::FindAccessTokenInfo(
399 const std::string& auth_token,
400 const std::string& client_id,
401 const std::string& scope_string) const {
402 if (auth_token.empty() || client_id.empty())
403 return NULL;
405 std::vector<std::string> scope_list;
406 base::SplitString(scope_string, ' ', &scope_list);
407 ScopeSet scopes(scope_list.begin(), scope_list.end());
409 for (AccessTokenInfoMap::const_iterator entry(
410 access_token_info_map_.lower_bound(auth_token));
411 entry != access_token_info_map_.upper_bound(auth_token);
412 ++entry) {
413 if (entry->second.audience == client_id &&
414 (scope_string.empty() || entry->second.scopes == scopes)) {
415 return &(entry->second);
419 return NULL;
422 const FakeGaia::AccessTokenInfo* FakeGaia::GetAccessTokenInfo(
423 const std::string& access_token) const {
424 for (AccessTokenInfoMap::const_iterator entry(
425 access_token_info_map_.begin());
426 entry != access_token_info_map_.end();
427 ++entry) {
428 if (entry->second.token == access_token)
429 return &(entry->second);
432 return NULL;
435 void FakeGaia::HandleServiceLogin(const HttpRequest& request,
436 BasicHttpResponse* http_response) {
437 http_response->set_code(net::HTTP_OK);
438 http_response->set_content(service_login_response_);
439 http_response->set_content_type("text/html");
442 void FakeGaia::HandleEmbeddedSetupChromeos(const HttpRequest& request,
443 BasicHttpResponse* http_response) {
444 http_response->set_code(net::HTTP_OK);
445 http_response->set_content(embedded_setup_chromeos_response_);
446 http_response->set_content_type("text/html");
449 void FakeGaia::HandleOAuthLogin(const HttpRequest& request,
450 BasicHttpResponse* http_response) {
451 http_response->set_code(net::HTTP_UNAUTHORIZED);
452 if (merge_session_params_.gaia_uber_token.empty()) {
453 http_response->set_code(net::HTTP_FORBIDDEN);
454 return;
457 std::string access_token;
458 if (!GetAccessToken(request, kAuthHeaderBearer, &access_token) &&
459 !GetAccessToken(request, kAuthHeaderOAuth, &access_token)) {
460 LOG(ERROR) << "/OAuthLogin missing access token in the header";
461 return;
464 GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
465 std::string request_query = request_url.query();
467 std::string source;
468 if (!GetQueryParameter(request_query, "source", &source) &&
469 !GetQueryParameter(request.content, "source", &source)) {
470 LOG(ERROR) << "Missing 'source' param in /OAuthLogin call";
471 return;
474 std::string issue_uberauth;
475 if (GetQueryParameter(request_query, "issueuberauth", &issue_uberauth) &&
476 issue_uberauth == "1") {
477 http_response->set_content(merge_session_params_.gaia_uber_token);
478 http_response->set_code(net::HTTP_OK);
479 // Issue GAIA uber token.
480 } else {
481 http_response->set_content(base::StringPrintf(
482 "SID=%s\nLSID=%s\nAuth=%s",
483 kTestOAuthLoginSID, kTestOAuthLoginLSID, kTestOAuthLoginAuthCode));
484 http_response->set_code(net::HTTP_OK);
488 void FakeGaia::HandleServiceLoginAuth(const HttpRequest& request,
489 BasicHttpResponse* http_response) {
490 std::string continue_url =
491 GaiaUrls::GetInstance()->service_login_url().spec();
492 GetQueryParameter(request.content, "continue", &continue_url);
494 std::string redirect_url = continue_url;
496 std::string email;
497 const bool is_saml =
498 GetQueryParameter(request.content, "Email", &email) &&
499 saml_account_idp_map_.find(email) != saml_account_idp_map_.end();
501 if (is_saml) {
502 GURL url(saml_account_idp_map_[email]);
503 url = net::AppendQueryParameter(url, "SAMLRequest", "fake_request");
504 url = net::AppendQueryParameter(url, "RelayState", continue_url);
505 redirect_url = url.spec();
506 http_response->AddCustomHeader("Google-Accounts-SAML", "Start");
507 } else if (!merge_session_params_.auth_sid_cookie.empty() &&
508 !merge_session_params_.auth_lsid_cookie.empty()) {
509 SetCookies(http_response,
510 merge_session_params_.auth_sid_cookie,
511 merge_session_params_.auth_lsid_cookie);
514 http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
515 http_response->AddCustomHeader("Location", redirect_url);
517 // SAML sign-ins complete in HandleSSO().
518 if (is_saml)
519 return;
521 AddGoogleAccountsSigninHeader(http_response, email);
522 if (issue_oauth_code_cookie_)
523 SetOAuthCodeCookie(http_response);
526 void FakeGaia::HandleEmbeddedLookupAccountLookup(
527 const net::test_server::HttpRequest& request,
528 net::test_server::BasicHttpResponse* http_response) {
529 std::string email;
530 const bool is_saml =
531 GetQueryParameter(request.content, "identifier", &email) &&
532 saml_account_idp_map_.find(email) != saml_account_idp_map_.end();
534 if (!is_saml)
535 return;
537 GURL url(saml_account_idp_map_[email]);
538 url = net::AppendQueryParameter(url, "SAMLRequest", "fake_request");
539 url = net::AppendQueryParameter(
540 url, "RelayState",
541 "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/success.html");
542 std::string redirect_url = url.spec();
543 http_response->AddCustomHeader("Google-Accounts-SAML", "Start");
545 http_response->AddCustomHeader("continue", redirect_url);
548 void FakeGaia::HandleEmbeddedSigninChallenge(const HttpRequest& request,
549 BasicHttpResponse* http_response) {
550 std::string email;
551 GetQueryParameter(request.content, "identifier", &email);
553 if (!merge_session_params_.auth_sid_cookie.empty() &&
554 !merge_session_params_.auth_lsid_cookie.empty()) {
555 SetCookies(http_response, merge_session_params_.auth_sid_cookie,
556 merge_session_params_.auth_lsid_cookie);
559 AddGoogleAccountsSigninHeader(http_response, email);
561 if (issue_oauth_code_cookie_)
562 SetOAuthCodeCookie(http_response);
565 void FakeGaia::HandleSSO(const HttpRequest& request,
566 BasicHttpResponse* http_response) {
567 if (!merge_session_params_.auth_sid_cookie.empty() &&
568 !merge_session_params_.auth_lsid_cookie.empty()) {
569 SetCookies(http_response,
570 merge_session_params_.auth_sid_cookie,
571 merge_session_params_.auth_lsid_cookie);
573 std::string relay_state;
574 GetQueryParameter(request.content, "RelayState", &relay_state);
575 std::string redirect_url = relay_state;
576 http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
577 http_response->AddCustomHeader("Location", redirect_url);
578 http_response->AddCustomHeader("Google-Accounts-SAML", "End");
580 if (!merge_session_params_.email.empty())
581 AddGoogleAccountsSigninHeader(http_response, merge_session_params_.email);
583 if (issue_oauth_code_cookie_)
584 SetOAuthCodeCookie(http_response);
587 void FakeGaia::HandleAuthToken(const HttpRequest& request,
588 BasicHttpResponse* http_response) {
589 std::string grant_type;
590 if (!GetQueryParameter(request.content, "grant_type", &grant_type)) {
591 http_response->set_code(net::HTTP_BAD_REQUEST);
592 LOG(ERROR) << "No 'grant_type' param in /o/oauth2/token";
593 return;
596 if (grant_type == "authorization_code") {
597 std::string auth_code;
598 if (!GetQueryParameter(request.content, "code", &auth_code) ||
599 auth_code != merge_session_params_.auth_code) {
600 http_response->set_code(net::HTTP_BAD_REQUEST);
601 LOG(ERROR) << "No 'code' param in /o/oauth2/token";
602 return;
605 base::DictionaryValue response_dict;
606 response_dict.SetString("refresh_token",
607 merge_session_params_.refresh_token);
608 response_dict.SetString("access_token",
609 merge_session_params_.access_token);
610 response_dict.SetInteger("expires_in", 3600);
611 FormatJSONResponse(response_dict, http_response);
612 return;
615 std::string scope;
616 GetQueryParameter(request.content, "scope", &scope);
618 std::string refresh_token;
619 std::string client_id;
620 if (GetQueryParameter(request.content, "refresh_token", &refresh_token) &&
621 GetQueryParameter(request.content, "client_id", &client_id)) {
622 const AccessTokenInfo* token_info =
623 FindAccessTokenInfo(refresh_token, client_id, scope);
624 if (token_info) {
625 base::DictionaryValue response_dict;
626 response_dict.SetString("access_token", token_info->token);
627 response_dict.SetInteger("expires_in", 3600);
628 FormatJSONResponse(response_dict, http_response);
629 return;
633 LOG(ERROR) << "Bad request for /o/oauth2/token - "
634 << "refresh_token = " << refresh_token
635 << ", scope = " << scope
636 << ", client_id = " << client_id;
637 http_response->set_code(net::HTTP_BAD_REQUEST);
640 void FakeGaia::HandleTokenInfo(const HttpRequest& request,
641 BasicHttpResponse* http_response) {
642 const AccessTokenInfo* token_info = NULL;
643 std::string access_token;
644 if (GetQueryParameter(request.content, "access_token", &access_token))
645 token_info = GetAccessTokenInfo(access_token);
647 if (token_info) {
648 base::DictionaryValue response_dict;
649 response_dict.SetString("issued_to", token_info->issued_to);
650 response_dict.SetString("audience", token_info->audience);
651 response_dict.SetString("user_id", token_info->user_id);
652 std::vector<std::string> scope_vector(token_info->scopes.begin(),
653 token_info->scopes.end());
654 response_dict.SetString("scope", JoinString(scope_vector, " "));
655 response_dict.SetInteger("expires_in", token_info->expires_in);
656 response_dict.SetString("email", token_info->email);
657 FormatJSONResponse(response_dict, http_response);
658 } else {
659 http_response->set_code(net::HTTP_BAD_REQUEST);
663 void FakeGaia::HandleIssueToken(const HttpRequest& request,
664 BasicHttpResponse* http_response) {
665 std::string access_token;
666 std::string scope;
667 std::string client_id;
668 if (GetAccessToken(request, kAuthHeaderBearer, &access_token) &&
669 GetQueryParameter(request.content, "scope", &scope) &&
670 GetQueryParameter(request.content, "client_id", &client_id)) {
671 const AccessTokenInfo* token_info =
672 FindAccessTokenInfo(access_token, client_id, scope);
673 if (token_info) {
674 base::DictionaryValue response_dict;
675 response_dict.SetString("issueAdvice", "auto");
676 response_dict.SetString("expiresIn",
677 base::IntToString(token_info->expires_in));
678 response_dict.SetString("token", token_info->token);
679 FormatJSONResponse(response_dict, http_response);
680 return;
683 http_response->set_code(net::HTTP_BAD_REQUEST);
686 void FakeGaia::HandleListAccounts(const HttpRequest& request,
687 BasicHttpResponse* http_response) {
688 http_response->set_content(base::StringPrintf(
689 kListAccountsResponseFormat, merge_session_params_.email.c_str()));
690 http_response->set_code(net::HTTP_OK);
693 void FakeGaia::HandleGetUserInfo(const HttpRequest& request,
694 BasicHttpResponse* http_response) {
695 http_response->set_content(base::StringPrintf(
696 "email=%s\ndisplayEmail=%s",
697 merge_session_params_.email.c_str(),
698 merge_session_params_.email.c_str()));
699 http_response->set_code(net::HTTP_OK);
702 void FakeGaia::HandleOAuthUserInfo(
703 const net::test_server::HttpRequest& request,
704 net::test_server::BasicHttpResponse* http_response) {
705 const AccessTokenInfo* token_info = NULL;
706 std::string access_token;
707 if (GetAccessToken(request, kAuthHeaderBearer, &access_token) ||
708 GetAccessToken(request, kAuthHeaderOAuth, &access_token)) {
709 token_info = GetAccessTokenInfo(access_token);
712 if (token_info) {
713 base::DictionaryValue response_dict;
714 response_dict.SetString("id", GetGaiaIdOfEmail(token_info->email));
715 response_dict.SetString("email", token_info->email);
716 response_dict.SetString("verified_email", token_info->email);
717 FormatJSONResponse(response_dict, http_response);
718 } else {
719 http_response->set_code(net::HTTP_BAD_REQUEST);