blob: 9f4a8122a22dd269ddda7ef77469b73e130b6e7f [file] [log] [blame]
// 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<HttpResponse> 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<BasicHttpResponse> 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(
"<HTML><HEAD><SCRIPT>\n" + redirect_js + "\n</SCRIPT></HEAD></HTML>");
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<std::string> 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<HttpResponse>();
}
return http_response.PassAs<HttpResponse>();
}
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);
}