Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / google_apis / gaia / fake_gaia.cc
blob5622460f3e894df6ea63a4354e2956eb58a47c8d
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 // OAuth2 Authentication header value prefix.
60 const char kAuthHeaderBearer[] = "Bearer ";
61 const char kAuthHeaderOAuth[] = "OAuth ";
63 const char kListAccountsResponseFormat[] =
64 "[\"gaia.l.a.r\",[[\"gaia.l.a\",1,\"\",\"%s\",\"\",1,1,0]]]";
66 typedef std::map<std::string, std::string> CookieMap;
68 // Parses cookie name-value map our of |request|.
69 CookieMap GetRequestCookies(const HttpRequest& request) {
70 CookieMap result;
71 std::map<std::string, std::string>::const_iterator iter =
72 request.headers.find("Cookie");
73 if (iter != request.headers.end()) {
74 std::vector<std::string> cookie_nv_pairs;
75 base::SplitString(iter->second, ' ', &cookie_nv_pairs);
76 for(std::vector<std::string>::const_iterator cookie_line =
77 cookie_nv_pairs.begin();
78 cookie_line != cookie_nv_pairs.end();
79 ++cookie_line) {
80 std::vector<std::string> name_value;
81 base::SplitString(*cookie_line, '=', &name_value);
82 if (name_value.size() != 2)
83 continue;
85 std::string value = name_value[1];
86 if (value.size() && value[value.size() - 1] == ';')
87 value = value.substr(0, value.size() -1);
89 result.insert(std::make_pair(name_value[0], value));
92 return result;
95 // Extracts the |access_token| from authorization header of |request|.
96 bool GetAccessToken(const HttpRequest& request,
97 const char* auth_token_prefix,
98 std::string* access_token) {
99 std::map<std::string, std::string>::const_iterator auth_header_entry =
100 request.headers.find("Authorization");
101 if (auth_header_entry != request.headers.end()) {
102 if (StartsWithASCII(auth_header_entry->second, auth_token_prefix, true)) {
103 *access_token = auth_header_entry->second.substr(
104 strlen(auth_token_prefix));
105 return true;
109 return false;
112 void SetCookies(BasicHttpResponse* http_response,
113 const std::string& sid_cookie,
114 const std::string& lsid_cookie) {
115 http_response->AddCustomHeader(
116 "Set-Cookie",
117 base::StringPrintf("SID=%s; Path=/; HttpOnly", sid_cookie.c_str()));
118 http_response->AddCustomHeader(
119 "Set-Cookie",
120 base::StringPrintf("LSID=%s; Path=/; HttpOnly", lsid_cookie.c_str()));
123 } // namespace
125 FakeGaia::AccessTokenInfo::AccessTokenInfo()
126 : expires_in(3600) {}
128 FakeGaia::AccessTokenInfo::~AccessTokenInfo() {}
130 FakeGaia::MergeSessionParams::MergeSessionParams() {
133 FakeGaia::MergeSessionParams::~MergeSessionParams() {
136 FakeGaia::FakeGaia() : issue_oauth_code_cookie_(false) {
137 base::FilePath source_root_dir;
138 PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir);
139 CHECK(base::ReadFileToString(
140 source_root_dir.Append(base::FilePath(kServiceLogin)),
141 &service_login_response_));
144 FakeGaia::~FakeGaia() {}
146 void FakeGaia::SetFakeMergeSessionParams(
147 const std::string& email,
148 const std::string& auth_sid_cookie,
149 const std::string& auth_lsid_cookie) {
150 FakeGaia::MergeSessionParams params;
151 params.auth_sid_cookie = auth_sid_cookie;
152 params.auth_lsid_cookie = auth_lsid_cookie;
153 params.auth_code = kTestAuthCode;
154 params.refresh_token = kTestRefreshToken;
155 params.access_token = kTestAuthLoginAccessToken;
156 params.gaia_uber_token = kTestGaiaUberToken;
157 params.session_sid_cookie = kTestSessionSIDCookie;
158 params.session_lsid_cookie = kTestSessionLSIDCookie;
159 params.email = email;
160 SetMergeSessionParams(params);
163 void FakeGaia::SetMergeSessionParams(
164 const MergeSessionParams& params) {
165 merge_session_params_ = params;
168 void FakeGaia::MapEmailToGaiaId(const std::string& email,
169 const std::string& gaia_id) {
170 DCHECK(!email.empty());
171 DCHECK(!gaia_id.empty());
172 email_to_gaia_id_map_[email] = gaia_id;
175 std::string FakeGaia::GetGaiaIdOfEmail(const std::string& email) const {
176 DCHECK(!email.empty());
177 auto it = email_to_gaia_id_map_.find(email);
178 return it == email_to_gaia_id_map_.end() ? std::string(kDefaultGaiaId) :
179 it->second;
182 void FakeGaia::AddGoogleAccountsSigninHeader(
183 net::test_server::BasicHttpResponse* http_response,
184 const std::string& email) const {
185 DCHECK(!email.empty());
186 http_response->AddCustomHeader("google-accounts-signin",
187 base::StringPrintf(
188 "email=\"%s\", obfuscatedid=\"%s\", sessionindex=0",
189 email.c_str(), GetGaiaIdOfEmail(email).c_str()));
192 void FakeGaia::SetOAuthCodeCookie(
193 net::test_server::BasicHttpResponse* http_response) const {
194 http_response->AddCustomHeader(
195 "Set-Cookie",
196 base::StringPrintf(
197 "oauth_code=%s; Path=/o/GetOAuth2Token; Secure; HttpOnly;",
198 merge_session_params_.auth_code.c_str()));
201 void FakeGaia::Initialize() {
202 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
203 // Handles /MergeSession GAIA call.
204 REGISTER_RESPONSE_HANDLER(
205 gaia_urls->merge_session_url(), HandleMergeSession);
207 // Handles /o/oauth2/programmatic_auth GAIA call.
208 REGISTER_RESPONSE_HANDLER(
209 gaia_urls->client_login_to_oauth2_url(), HandleProgramaticAuth);
211 // Handles /ServiceLogin GAIA call.
212 REGISTER_RESPONSE_HANDLER(
213 gaia_urls->service_login_url(), HandleServiceLogin);
215 // Handles /embedded/setup/chromeos GAIA call.
216 // Same handler as for /ServiceLogin is used for now.
217 REGISTER_RESPONSE_HANDLER(
218 gaia_urls->embedded_setup_chromeos_url(), HandleServiceLogin);
220 // Handles /OAuthLogin GAIA call.
221 REGISTER_RESPONSE_HANDLER(
222 gaia_urls->oauth1_login_url(), HandleOAuthLogin);
224 // Handles /ServiceLoginAuth GAIA call.
225 REGISTER_RESPONSE_HANDLER(
226 gaia_urls->service_login_auth_url(), HandleServiceLoginAuth);
228 // Handles /SSO GAIA call (not GAIA, made up for SAML tests).
229 REGISTER_PATH_RESPONSE_HANDLER("/SSO", HandleSSO);
231 // Handles /o/oauth2/token GAIA call.
232 REGISTER_RESPONSE_HANDLER(
233 gaia_urls->oauth2_token_url(), HandleAuthToken);
235 // Handles /oauth2/v2/tokeninfo GAIA call.
236 REGISTER_RESPONSE_HANDLER(
237 gaia_urls->oauth2_token_info_url(), HandleTokenInfo);
239 // Handles /oauth2/v2/IssueToken GAIA call.
240 REGISTER_RESPONSE_HANDLER(
241 gaia_urls->oauth2_issue_token_url(), HandleIssueToken);
243 // Handles /ListAccounts GAIA call.
244 REGISTER_RESPONSE_HANDLER(
245 gaia_urls->ListAccountsURLWithSource(std::string()), HandleListAccounts);
247 // Handles /GetUserInfo GAIA call.
248 REGISTER_RESPONSE_HANDLER(
249 gaia_urls->get_user_info_url(), HandleGetUserInfo);
251 // Handles /oauth2/v1/userinfo call.
252 REGISTER_RESPONSE_HANDLER(
253 gaia_urls->oauth_user_info_url(), HandleOAuthUserInfo);
256 scoped_ptr<HttpResponse> FakeGaia::HandleRequest(const HttpRequest& request) {
257 // The scheme and host of the URL is actually not important but required to
258 // get a valid GURL in order to parse |request.relative_url|.
259 GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
260 std::string request_path = request_url.path();
261 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
262 RequestHandlerMap::iterator iter = request_handlers_.find(request_path);
263 if (iter != request_handlers_.end()) {
264 LOG(WARNING) << "Serving request " << request_path;
265 iter->second.Run(request, http_response.get());
266 } else {
267 LOG(ERROR) << "Unhandled request " << request_path;
268 return scoped_ptr<HttpResponse>(); // Request not understood.
271 return http_response.Pass();
274 void FakeGaia::IssueOAuthToken(const std::string& auth_token,
275 const AccessTokenInfo& token_info) {
276 access_token_info_map_.insert(std::make_pair(auth_token, token_info));
279 void FakeGaia::RegisterSamlUser(const std::string& account_id,
280 const GURL& saml_idp) {
281 saml_account_idp_map_[account_id] = saml_idp;
284 // static
285 bool FakeGaia::GetQueryParameter(const std::string& query,
286 const std::string& key,
287 std::string* value) {
288 // Name and scheme actually don't matter, but are required to get a valid URL
289 // for parsing.
290 GURL query_url("http://localhost?" + query);
291 return net::GetValueForKeyInQuery(query_url, key, value);
294 void FakeGaia::HandleMergeSession(const HttpRequest& request,
295 BasicHttpResponse* http_response) {
296 http_response->set_code(net::HTTP_UNAUTHORIZED);
297 if (merge_session_params_.session_sid_cookie.empty() ||
298 merge_session_params_.session_lsid_cookie.empty()) {
299 http_response->set_code(net::HTTP_BAD_REQUEST);
300 return;
303 std::string uber_token;
304 if (!GetQueryParameter(request.content, "uberauth", &uber_token) ||
305 uber_token != merge_session_params_.gaia_uber_token) {
306 LOG(ERROR) << "Missing or invalid 'uberauth' param in /MergeSession call";
307 return;
310 std::string continue_url;
311 if (!GetQueryParameter(request.content, "continue", &continue_url)) {
312 LOG(ERROR) << "Missing or invalid 'continue' param in /MergeSession call";
313 return;
316 std::string source;
317 if (!GetQueryParameter(request.content, "source", &source)) {
318 LOG(ERROR) << "Missing or invalid 'source' param in /MergeSession call";
319 return;
322 SetCookies(http_response,
323 merge_session_params_.session_sid_cookie,
324 merge_session_params_.session_lsid_cookie);
325 // TODO(zelidrag): Not used now.
326 http_response->set_content("OK");
327 http_response->set_code(net::HTTP_OK);
330 void FakeGaia::HandleProgramaticAuth(
331 const HttpRequest& request,
332 BasicHttpResponse* http_response) {
333 http_response->set_code(net::HTTP_UNAUTHORIZED);
334 if (merge_session_params_.auth_code.empty()) {
335 http_response->set_code(net::HTTP_BAD_REQUEST);
336 return;
339 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
340 std::string scope;
341 if (!GetQueryParameter(request.content, "scope", &scope) ||
342 GaiaConstants::kOAuth1LoginScope != scope) {
343 return;
346 CookieMap cookies = GetRequestCookies(request);
347 CookieMap::const_iterator sid_iter = cookies.find("SID");
348 if (sid_iter == cookies.end() ||
349 sid_iter->second != merge_session_params_.auth_sid_cookie) {
350 LOG(ERROR) << "/o/oauth2/programmatic_auth missing SID cookie";
351 return;
353 CookieMap::const_iterator lsid_iter = cookies.find("LSID");
354 if (lsid_iter == cookies.end() ||
355 lsid_iter->second != merge_session_params_.auth_lsid_cookie) {
356 LOG(ERROR) << "/o/oauth2/programmatic_auth missing LSID cookie";
357 return;
360 std::string client_id;
361 if (!GetQueryParameter(request.content, "client_id", &client_id) ||
362 gaia_urls->oauth2_chrome_client_id() != client_id) {
363 return;
366 http_response->AddCustomHeader(
367 "Set-Cookie",
368 base::StringPrintf(
369 "oauth_code=%s; Path=/o/GetOAuth2Token; Secure; HttpOnly;",
370 merge_session_params_.auth_code.c_str()));
371 http_response->set_code(net::HTTP_OK);
372 http_response->set_content_type("text/html");
375 void FakeGaia::FormatJSONResponse(const base::DictionaryValue& response_dict,
376 BasicHttpResponse* http_response) {
377 std::string response_json;
378 base::JSONWriter::Write(&response_dict, &response_json);
379 http_response->set_content(response_json);
380 http_response->set_code(net::HTTP_OK);
383 const FakeGaia::AccessTokenInfo* FakeGaia::FindAccessTokenInfo(
384 const std::string& auth_token,
385 const std::string& client_id,
386 const std::string& scope_string) const {
387 if (auth_token.empty() || client_id.empty())
388 return NULL;
390 std::vector<std::string> scope_list;
391 base::SplitString(scope_string, ' ', &scope_list);
392 ScopeSet scopes(scope_list.begin(), scope_list.end());
394 for (AccessTokenInfoMap::const_iterator entry(
395 access_token_info_map_.lower_bound(auth_token));
396 entry != access_token_info_map_.upper_bound(auth_token);
397 ++entry) {
398 if (entry->second.audience == client_id &&
399 (scope_string.empty() || entry->second.scopes == scopes)) {
400 return &(entry->second);
404 return NULL;
407 const FakeGaia::AccessTokenInfo* FakeGaia::GetAccessTokenInfo(
408 const std::string& access_token) const {
409 for (AccessTokenInfoMap::const_iterator entry(
410 access_token_info_map_.begin());
411 entry != access_token_info_map_.end();
412 ++entry) {
413 if (entry->second.token == access_token)
414 return &(entry->second);
417 return NULL;
420 void FakeGaia::HandleServiceLogin(const HttpRequest& request,
421 BasicHttpResponse* http_response) {
422 http_response->set_code(net::HTTP_OK);
423 http_response->set_content(service_login_response_);
424 http_response->set_content_type("text/html");
427 void FakeGaia::HandleOAuthLogin(const HttpRequest& request,
428 BasicHttpResponse* http_response) {
429 http_response->set_code(net::HTTP_UNAUTHORIZED);
430 if (merge_session_params_.gaia_uber_token.empty()) {
431 http_response->set_code(net::HTTP_FORBIDDEN);
432 return;
435 std::string access_token;
436 if (!GetAccessToken(request, kAuthHeaderBearer, &access_token) &&
437 !GetAccessToken(request, kAuthHeaderOAuth, &access_token)) {
438 LOG(ERROR) << "/OAuthLogin missing access token in the header";
439 return;
442 GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
443 std::string request_query = request_url.query();
445 std::string source;
446 if (!GetQueryParameter(request_query, "source", &source) &&
447 !GetQueryParameter(request.content, "source", &source)) {
448 LOG(ERROR) << "Missing 'source' param in /OAuthLogin call";
449 return;
452 std::string issue_uberauth;
453 if (GetQueryParameter(request_query, "issueuberauth", &issue_uberauth) &&
454 issue_uberauth == "1") {
455 http_response->set_content(merge_session_params_.gaia_uber_token);
456 http_response->set_code(net::HTTP_OK);
457 // Issue GAIA uber token.
458 } else {
459 http_response->set_content(base::StringPrintf(
460 "SID=%s\nLSID=%s\nAuth=%s",
461 kTestOAuthLoginSID, kTestOAuthLoginLSID, kTestOAuthLoginAuthCode));
462 http_response->set_code(net::HTTP_OK);
466 void FakeGaia::HandleServiceLoginAuth(const HttpRequest& request,
467 BasicHttpResponse* http_response) {
468 std::string continue_url =
469 GaiaUrls::GetInstance()->service_login_url().spec();
470 GetQueryParameter(request.content, "continue", &continue_url);
472 std::string redirect_url = continue_url;
474 std::string email;
475 const bool is_saml =
476 GetQueryParameter(request.content, "Email", &email) &&
477 saml_account_idp_map_.find(email) != saml_account_idp_map_.end();
479 if (is_saml) {
480 GURL url(saml_account_idp_map_[email]);
481 url = net::AppendQueryParameter(url, "SAMLRequest", "fake_request");
482 url = net::AppendQueryParameter(url, "RelayState", continue_url);
483 redirect_url = url.spec();
484 http_response->AddCustomHeader("Google-Accounts-SAML", "Start");
485 } else if (!merge_session_params_.auth_sid_cookie.empty() &&
486 !merge_session_params_.auth_lsid_cookie.empty()) {
487 SetCookies(http_response,
488 merge_session_params_.auth_sid_cookie,
489 merge_session_params_.auth_lsid_cookie);
492 http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
493 http_response->AddCustomHeader("Location", redirect_url);
495 // SAML sign-ins complete in HandleSSO().
496 if (is_saml)
497 return;
499 AddGoogleAccountsSigninHeader(http_response, email);
500 if (issue_oauth_code_cookie_)
501 SetOAuthCodeCookie(http_response);
504 void FakeGaia::HandleSSO(const HttpRequest& request,
505 BasicHttpResponse* http_response) {
506 if (!merge_session_params_.auth_sid_cookie.empty() &&
507 !merge_session_params_.auth_lsid_cookie.empty()) {
508 SetCookies(http_response,
509 merge_session_params_.auth_sid_cookie,
510 merge_session_params_.auth_lsid_cookie);
512 std::string relay_state;
513 GetQueryParameter(request.content, "RelayState", &relay_state);
514 std::string redirect_url = relay_state;
515 http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
516 http_response->AddCustomHeader("Location", redirect_url);
517 http_response->AddCustomHeader("Google-Accounts-SAML", "End");
519 if (!merge_session_params_.email.empty())
520 AddGoogleAccountsSigninHeader(http_response, merge_session_params_.email);
522 if (issue_oauth_code_cookie_)
523 SetOAuthCodeCookie(http_response);
526 void FakeGaia::HandleAuthToken(const HttpRequest& request,
527 BasicHttpResponse* http_response) {
528 std::string grant_type;
529 if (!GetQueryParameter(request.content, "grant_type", &grant_type)) {
530 http_response->set_code(net::HTTP_BAD_REQUEST);
531 LOG(ERROR) << "No 'grant_type' param in /o/oauth2/token";
532 return;
535 if (grant_type == "authorization_code") {
536 std::string auth_code;
537 if (!GetQueryParameter(request.content, "code", &auth_code) ||
538 auth_code != merge_session_params_.auth_code) {
539 http_response->set_code(net::HTTP_BAD_REQUEST);
540 LOG(ERROR) << "No 'code' param in /o/oauth2/token";
541 return;
544 base::DictionaryValue response_dict;
545 response_dict.SetString("refresh_token",
546 merge_session_params_.refresh_token);
547 response_dict.SetString("access_token",
548 merge_session_params_.access_token);
549 response_dict.SetInteger("expires_in", 3600);
550 FormatJSONResponse(response_dict, http_response);
551 return;
554 std::string scope;
555 GetQueryParameter(request.content, "scope", &scope);
557 std::string refresh_token;
558 std::string client_id;
559 if (GetQueryParameter(request.content, "refresh_token", &refresh_token) &&
560 GetQueryParameter(request.content, "client_id", &client_id)) {
561 const AccessTokenInfo* token_info =
562 FindAccessTokenInfo(refresh_token, client_id, scope);
563 if (token_info) {
564 base::DictionaryValue response_dict;
565 response_dict.SetString("access_token", token_info->token);
566 response_dict.SetInteger("expires_in", 3600);
567 FormatJSONResponse(response_dict, http_response);
568 return;
572 LOG(ERROR) << "Bad request for /o/oauth2/token - "
573 << "refresh_token = " << refresh_token
574 << ", scope = " << scope
575 << ", client_id = " << client_id;
576 http_response->set_code(net::HTTP_BAD_REQUEST);
579 void FakeGaia::HandleTokenInfo(const HttpRequest& request,
580 BasicHttpResponse* http_response) {
581 const AccessTokenInfo* token_info = NULL;
582 std::string access_token;
583 if (GetQueryParameter(request.content, "access_token", &access_token))
584 token_info = GetAccessTokenInfo(access_token);
586 if (token_info) {
587 base::DictionaryValue response_dict;
588 response_dict.SetString("issued_to", token_info->issued_to);
589 response_dict.SetString("audience", token_info->audience);
590 response_dict.SetString("user_id", token_info->user_id);
591 std::vector<std::string> scope_vector(token_info->scopes.begin(),
592 token_info->scopes.end());
593 response_dict.SetString("scope", JoinString(scope_vector, " "));
594 response_dict.SetInteger("expires_in", token_info->expires_in);
595 response_dict.SetString("email", token_info->email);
596 FormatJSONResponse(response_dict, http_response);
597 } else {
598 http_response->set_code(net::HTTP_BAD_REQUEST);
602 void FakeGaia::HandleIssueToken(const HttpRequest& request,
603 BasicHttpResponse* http_response) {
604 std::string access_token;
605 std::string scope;
606 std::string client_id;
607 if (GetAccessToken(request, kAuthHeaderBearer, &access_token) &&
608 GetQueryParameter(request.content, "scope", &scope) &&
609 GetQueryParameter(request.content, "client_id", &client_id)) {
610 const AccessTokenInfo* token_info =
611 FindAccessTokenInfo(access_token, client_id, scope);
612 if (token_info) {
613 base::DictionaryValue response_dict;
614 response_dict.SetString("issueAdvice", "auto");
615 response_dict.SetString("expiresIn",
616 base::IntToString(token_info->expires_in));
617 response_dict.SetString("token", token_info->token);
618 FormatJSONResponse(response_dict, http_response);
619 return;
622 http_response->set_code(net::HTTP_BAD_REQUEST);
625 void FakeGaia::HandleListAccounts(const HttpRequest& request,
626 BasicHttpResponse* http_response) {
627 http_response->set_content(base::StringPrintf(
628 kListAccountsResponseFormat, merge_session_params_.email.c_str()));
629 http_response->set_code(net::HTTP_OK);
632 void FakeGaia::HandleGetUserInfo(const HttpRequest& request,
633 BasicHttpResponse* http_response) {
634 http_response->set_content(base::StringPrintf(
635 "email=%s\ndisplayEmail=%s",
636 merge_session_params_.email.c_str(),
637 merge_session_params_.email.c_str()));
638 http_response->set_code(net::HTTP_OK);
641 void FakeGaia::HandleOAuthUserInfo(
642 const net::test_server::HttpRequest& request,
643 net::test_server::BasicHttpResponse* http_response) {
644 const AccessTokenInfo* token_info = NULL;
645 std::string access_token;
646 if (GetAccessToken(request, kAuthHeaderBearer, &access_token) ||
647 GetAccessToken(request, kAuthHeaderOAuth, &access_token)) {
648 token_info = GetAccessTokenInfo(access_token);
651 if (token_info) {
652 base::DictionaryValue response_dict;
653 response_dict.SetString("id", GetGaiaIdOfEmail(token_info->email));
654 response_dict.SetString("email", token_info->email);
655 response_dict.SetString("verified_email", token_info->email);
656 FormatJSONResponse(response_dict, http_response);
657 } else {
658 http_response->set_code(net::HTTP_BAD_REQUEST);