From 3014321f5622f30e8e7f88fdb55bcc0e612b4f65 Mon Sep 17 00:00:00 2001 From: "mnissler@chromium.org" Date: Thu, 19 Sep 2013 11:21:12 +0000 Subject: Add a fake GAIA implementation for use with the test server. This is for the benefit of integration tests that need the browser to interface with GAIA and friends, such as for OAuth2 token minting. BUG=chromium:243889 R=joi@chromium.org, xiyuan@chromium.org, zelidrag@chromium.org Review URL: https://codereview.chromium.org/24172005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@224108 0039d316-1c4b-4281-b951-d872f2087c98 --- google_apis/gaia/fake_gaia.cc | 143 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 google_apis/gaia/fake_gaia.cc (limited to 'google_apis/gaia/fake_gaia.cc') diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc new file mode 100644 index 0000000..9f4a812 --- /dev/null +++ b/google_apis/gaia/fake_gaia.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "google_apis/gaia/fake_gaia.h" + +#include "base/base_paths.h" +#include "base/file_util.h" +#include "base/files/file_path.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/strings/string_util.h" +#include "base/values.h" +#include "google_apis/gaia/gaia_urls.h" +#include "net/base/url_util.h" +#include "net/http/http_status_code.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "url/url_parse.h" + +using namespace net::test_server; + +namespace { +const base::FilePath::CharType kServiceLogin[] = + FILE_PATH_LITERAL("google_apis/test/service_login.html"); +} + +FakeGaia::AccessTokenInfo::AccessTokenInfo() + : expires_in(3600) {} + +FakeGaia::AccessTokenInfo::~AccessTokenInfo() {} + +FakeGaia::FakeGaia() { + base::FilePath source_root_dir; + PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir); + CHECK(base::ReadFileToString( + source_root_dir.Append(base::FilePath(kServiceLogin)), + &service_login_response_)); +} + +FakeGaia::~FakeGaia() {} + +scoped_ptr FakeGaia::HandleRequest(const HttpRequest& request) { + GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); + + // The scheme and host of the URL is actually not important but required to + // get a valid GURL in order to parse |request.relative_url|. + GURL request_url = GURL("http://localhost").Resolve(request.relative_url); + std::string request_path = request_url.path(); + + scoped_ptr http_response(new BasicHttpResponse()); + if (request_path == gaia_urls->service_login_url().path()) { + http_response->set_code(net::HTTP_OK); + http_response->set_content(service_login_response_); + http_response->set_content_type("text/html"); + } else if (request_path == gaia_urls->service_login_auth_url().path()) { + std::string continue_url = gaia_urls->service_login_url().spec(); + GetQueryParameter(request.content, "continue", &continue_url); + http_response->set_code(net::HTTP_OK); + const std::string redirect_js = + "document.location.href = '" + continue_url + "'"; + http_response->set_content( + ""); + http_response->set_content_type("text/html"); + } else if (request_path == gaia_urls->oauth2_token_url().path()) { + std::string refresh_token; + const AccessTokenInfo* token_info = NULL; + if (GetQueryParameter(request.content, "refresh_token", &refresh_token) && + (token_info = GetAccessTokenInfo(refresh_token))) { + base::DictionaryValue response_dict; + response_dict.SetString("access_token", token_info->token); + response_dict.SetInteger("expires_in", 3600); + FormatJSONResponse(response_dict, http_response.get()); + } else { + http_response->set_code(net::HTTP_BAD_REQUEST); + } + } else if (request_path == gaia_urls->oauth2_token_info_url().path()) { + const AccessTokenInfo* token_info = NULL; + std::string access_token; + if (GetQueryParameter(request.content, "access_token", &access_token)) { + for (AccessTokenInfoMap::const_iterator entry( + access_token_info_map_.begin()); + entry != access_token_info_map_.end(); + ++entry) { + if (entry->second.token == access_token) { + token_info = &(entry->second); + break; + } + } + } + + if (token_info) { + base::DictionaryValue response_dict; + response_dict.SetString("issued_to", token_info->issued_to); + response_dict.SetString("audience", token_info->audience); + response_dict.SetString("user_id", token_info->user_id); + std::vector scope_vector(token_info->scopes.begin(), + token_info->scopes.end()); + response_dict.SetString("scope", JoinString(scope_vector, " ")); + response_dict.SetInteger("expires_in", token_info->expires_in); + response_dict.SetString("email", token_info->email); + FormatJSONResponse(response_dict, http_response.get()); + } else { + http_response->set_code(net::HTTP_BAD_REQUEST); + } + } else { + // Request not understood. + return scoped_ptr(); + } + + return http_response.PassAs(); +} + +void FakeGaia::IssueOAuthToken(const std::string& refresh_token, + const AccessTokenInfo& token_info) { + access_token_info_map_[refresh_token] = token_info; +} + +void FakeGaia::FormatJSONResponse(const base::DictionaryValue& response_dict, + BasicHttpResponse* http_response) { + std::string response_json; + base::JSONWriter::Write(&response_dict, &response_json); + http_response->set_content(response_json); + http_response->set_code(net::HTTP_OK); +} + +const FakeGaia::AccessTokenInfo* FakeGaia::GetAccessTokenInfo( + const std::string& refresh_token) const { + AccessTokenInfoMap::const_iterator entry = + access_token_info_map_.find(refresh_token); + return entry == access_token_info_map_.end() ? NULL : &entry->second; +} + +// static +bool FakeGaia::GetQueryParameter(const std::string& query, + const std::string& key, + std::string* value) { + // Name and scheme actually don't matter, but are required to get a valid URL + // for parsing. + GURL query_url("http://localhost?" + query); + return net::GetValueForKeyInQuery(query_url, key, value); +} -- cgit v1.1