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

Unified Diff: google_apis/gaia/fake_gaia.cc

Issue 99863007: Added CrOS-specific OAuth2 browser test. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 side-by-side diff with in-line comments
Download patch
« google_apis/gaia/fake_gaia.h ('K') | « google_apis/gaia/fake_gaia.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: google_apis/gaia/fake_gaia.cc
diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc
index 322ed54ff9fc4a72b75c6c82009ee301c698f401..bbffd7c8c8121bdb7d36895b8b83ac832d4264f4 100644
--- a/google_apis/gaia/fake_gaia.cc
+++ b/google_apis/gaia/fake_gaia.cc
@@ -5,6 +5,8 @@
#include "google_apis/gaia/fake_gaia.h"
#include "base/base_paths.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
@@ -13,6 +15,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/url_util.h"
@@ -21,11 +24,21 @@
#include "net/test/embedded_test_server/http_response.h"
#include "url/url_parse.h"
+#define REGISTER_RESPONSE_HANDLER(url, method) \
+ request_handlers_.insert(std::make_pair( \
+ url.path(), base::Bind(&FakeGaia::method, base::Unretained(this))))
+
using namespace net::test_server;
namespace {
+
const base::FilePath::CharType kServiceLogin[] =
FILE_PATH_LITERAL("google_apis/test/service_login.html");
+
+// OAuth2 Authentication header value prefix.
+const char kAuthHeaderBearer[] = "Bearer ";
+const char kAuthHeaderOAuth[] = "OAuth ";
+
}
FakeGaia::AccessTokenInfo::AccessTokenInfo()
@@ -43,100 +56,290 @@ FakeGaia::FakeGaia() {
FakeGaia::~FakeGaia() {}
-scoped_ptr<HttpResponse> FakeGaia::HandleRequest(const HttpRequest& request) {
+void FakeGaia::SetAuthTokens(const std::string& auth_code,
+ const std::string& refresh_token,
+ const std::string& access_token,
+ const std::string& gaia_uber_token,
+ const std::string& session_sid_cookie,
+ const std::string& session_lsid_cookie) {
+ fake_auth_code_ = auth_code;
+ fake_refresh_token_ = refresh_token;
+ fake_access_token_ = access_token;
+ fake_gaia_uber_token_ = gaia_uber_token;
+ fake_session_sid_cookie_ = session_sid_cookie;
+ fake_session_lsid_cookie_ = session_lsid_cookie;
+}
+
+void FakeGaia::Initialize() {
GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
+ // Handles /ServiceLogin GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->service_login_url(), HandleServiceLogin);
+
+ // Handles /ServiceLoginAuth GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->service_login_auth_url(), HandleServiceLoginAuth);
+
+ // Handles /o/oauth2/programmatic_auth GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->client_login_to_oauth2_url(), HandleProgramaticAuth);
+
+ // Handles /o/oauth2/token GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->oauth2_token_url(), HandleAuthToken);
+
+ // Handles /OAuthLogin GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->oauth1_login_url(), HandleOAuthLogin);
+
+ // Handles /MergeSession GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->merge_session_url(), HandleMergeSession);
+
+ // Handles /o/oauth2/token GAIA call.
Roger Tawa OOO till Jul 10th 2013/12/16 20:44:37 Same as line 87 above?
zel 2013/12/16 21:27:38 Done.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->oauth2_issue_token_url(), HandleIssueToken);
+
+ // Handles /oauth2/v2/tokeninfo GAIA call.
+ REGISTER_RESPONSE_HANDLER(
+ gaia_urls->oauth2_token_info_url(), HandleTokenInfo);
+}
+
+void FakeGaia::HandleProgramaticAuth(
+ const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
+ std::string scope;
+ if (!GetQueryParameter(request.content, "scope", &scope) ||
+ gaia_urls->oauth1_login_scope() != scope) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ return;
+ }
+
+ std::string client_id;
+ if (!GetQueryParameter(request.content, "client_id", &client_id) ||
+ gaia_urls->oauth2_chrome_client_id() != client_id) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ return;
+ }
+
+ http_response->AddCustomHeader(
+ "Set-Cookie",
+ base::StringPrintf(
+ "oauth_code=%s; Path=/o/GetOAuth2Token; Secure; HttpOnly;",
+ fake_auth_code_.c_str()));
+ http_response->set_code(net::HTTP_OK);
+ http_response->set_content_type("text/html");
+}
+
+void FakeGaia::HandleServiceLogin(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ http_response->set_code(net::HTTP_OK);
+ http_response->set_content(service_login_response_);
+ http_response->set_content_type("text/html");
+}
+
+void FakeGaia::HandleOAuthLogin(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ std::string access_token;
+ if (!GetAccessToken(request, kAuthHeaderOAuth, &access_token)) {
+ LOG(ERROR) << "/OAuthLogin missing access token in the header";
+ return;
+ }
- // 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();
+ std::string request_query = request_url.query();
- 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);
+ std::string source;
+ if (!GetQueryParameter(request_query, "source", &source)) {
+ LOG(ERROR) << "Missing 'source' param in /OAuthLogin call";
+ return;
+ }
+
+ std::string issue_uberauth;
+ if (GetQueryParameter(request_query, "issueuberauth", &issue_uberauth) &&
+ issue_uberauth == "1") {
+ http_response->set_content(fake_gaia_uber_token_);
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;
- std::string client_id;
- std::string scope;
- const AccessTokenInfo* token_info = NULL;
- GetQueryParameter(request.content, "scope", &scope);
- if (GetQueryParameter(request.content, "refresh_token", &refresh_token) &&
- GetQueryParameter(request.content, "client_id", &client_id) &&
- (token_info = GetAccessTokenInfo(refresh_token, client_id, scope))) {
- 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 {
+ // Issue GAIA uber token.
+ } else {
+ LOG(FATAL) << "/OAuthLogin for SID/LSID is not supported";
+ }
+}
+
+void FakeGaia::HandleMergeSession(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+
+ std::string uber_token;
+ if (!GetQueryParameter(request.content, "uberauth", &uber_token) ||
+ uber_token != fake_gaia_uber_token_) {
+ LOG(ERROR) << "Missing or invalid 'uberauth' param in /MergeSession call";
+ return;
+ }
+
+ std::string continue_url;
+ if (!GetQueryParameter(request.content, "continue", &continue_url)) {
+ LOG(ERROR) << "Missing or invalid 'continue' param in /MergeSession call";
+ return;
+ }
+
+ std::string source;
+ if (!GetQueryParameter(request.content, "source", &source)) {
+ LOG(ERROR) << "Missing or invalid 'source' param in /MergeSession call";
+ return;
+ }
+
+ http_response->AddCustomHeader(
+ "Set-Cookie",
+ base::StringPrintf(
+ "SID=%s; LSID=%s; Path=/; Secure; HttpOnly;",
+ fake_session_sid_cookie_.c_str(),
+ fake_session_lsid_cookie_.c_str()));
+ // TODO(zelidrag): Not used now.
+ http_response->set_content("OK");
+ http_response->set_code(net::HTTP_OK);
+}
+
+
+void FakeGaia::HandleServiceLoginAuth(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ std::string continue_url =
+ GaiaUrls::GetInstance()->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");
+}
+
+void FakeGaia::HandleAuthToken(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ std::string grant_type;
+ std::string refresh_token;
+ std::string client_id;
+ std::string scope;
+ std::string auth_code;
+ const AccessTokenInfo* token_info = NULL;
+ GetQueryParameter(request.content, "scope", &scope);
+
+ if (!GetQueryParameter(request.content, "grant_type", &grant_type)) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ LOG(ERROR) << "No 'grant_type' param in /o/oauth2/token";
+ return;
+ }
+
+ if (grant_type == "authorization_code") {
+ if (!GetQueryParameter(request.content, "code", &auth_code) ||
+ auth_code != fake_auth_code_) {
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;
- }
- }
+ LOG(ERROR) << "No 'code' param in /o/oauth2/token";
+ return;
}
- 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 {
+ if (GaiaUrls::GetInstance()->oauth1_login_scope() != scope) {
http_response->set_code(net::HTTP_BAD_REQUEST);
- }
- } else if (request_path == gaia_urls->oauth2_issue_token_url().path()) {
- std::string access_token;
- std::map<std::string, std::string>::const_iterator auth_header_entry =
- request.headers.find("Authorization");
- if (auth_header_entry != request.headers.end()) {
- if (StartsWithASCII(auth_header_entry->second, "Bearer ", true))
- access_token = auth_header_entry->second.substr(7);
+ LOG(ERROR) << "Invalid scope for /o/oauth2/token - " << scope;
+ return;
}
- std::string scope;
- std::string client_id;
- const AccessTokenInfo* token_info = NULL;
- if (GetQueryParameter(request.content, "scope", &scope) &&
- GetQueryParameter(request.content, "client_id", &client_id) &&
- (token_info = GetAccessTokenInfo(access_token, client_id, scope))) {
- base::DictionaryValue response_dict;
- response_dict.SetString("issueAdvice", "auto");
- response_dict.SetString("expiresIn",
- base::IntToString(token_info->expires_in));
- response_dict.SetString("token", token_info->token);
- FormatJSONResponse(response_dict, http_response.get());
- } else {
- http_response->set_code(net::HTTP_BAD_REQUEST);
+ base::DictionaryValue response_dict;
+ response_dict.SetString("refresh_token", fake_refresh_token_);
+ response_dict.SetString("access_token", fake_access_token_);
+ response_dict.SetInteger("expires_in", 3600);
+ FormatJSONResponse(response_dict, http_response);
+ } else if (GetQueryParameter(request.content,
+ "refresh_token",
+ &refresh_token) &&
+ GetQueryParameter(request.content,
+ "client_id",
+ &client_id) &&
+ (token_info = FindAccessTokenInfo(refresh_token,
+ client_id,
+ scope))) {
+ base::DictionaryValue response_dict;
+ response_dict.SetString("access_token", token_info->token);
+ response_dict.SetInteger("expires_in", 3600);
+ FormatJSONResponse(response_dict, http_response);
+ } else {
+ LOG(ERROR) << "Bad request for /o/oauth2/token - "
+ << "refresh_token = " << refresh_token
+ << ", scope = " << scope
+ << ", client_id = " << client_id;
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ }
+}
+
+void FakeGaia::HandleTokenInfo(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ 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);
+ } else {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ }
+}
+
+void FakeGaia::HandleIssueToken(const HttpRequest& request,
+ BasicHttpResponse* http_response) {
+ std::string access_token;
+ std::string scope;
+ std::string client_id;
+ const AccessTokenInfo* token_info = NULL;
+ if (GetAccessToken(request, kAuthHeaderBearer, &access_token) &&
+ GetQueryParameter(request.content, "scope", &scope) &&
+ GetQueryParameter(request.content, "client_id", &client_id) &&
+ (token_info = FindAccessTokenInfo(access_token, client_id, scope))) {
+ base::DictionaryValue response_dict;
+ response_dict.SetString("issueAdvice", "auto");
+ response_dict.SetString("expiresIn",
+ base::IntToString(token_info->expires_in));
+ response_dict.SetString("token", token_info->token);
+ FormatJSONResponse(response_dict, http_response);
+ } else {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ }
+}
+
+
+scoped_ptr<HttpResponse> FakeGaia::HandleRequest(const HttpRequest& request) {
+ // 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());
+ RequestHandlerMap::iterator iter = request_handlers_.find(request_path);
+ if (iter != request_handlers_.end()) {
+ LOG(WARNING) << "Serving request " << request_path;
+ iter->second.Run(request, http_response.get());
} else {
- // Request not understood.
- return scoped_ptr<HttpResponse>();
+ LOG(ERROR) << "Unhandled request " << request_path;
+ return scoped_ptr<HttpResponse>(); // Request not understood.
}
return http_response.PassAs<HttpResponse>();
@@ -155,7 +358,7 @@ void FakeGaia::FormatJSONResponse(const base::DictionaryValue& response_dict,
http_response->set_code(net::HTTP_OK);
}
-const FakeGaia::AccessTokenInfo* FakeGaia::GetAccessTokenInfo(
+const FakeGaia::AccessTokenInfo* FakeGaia::FindAccessTokenInfo(
const std::string& auth_token,
const std::string& client_id,
const std::string& scope_string) const {
@@ -188,3 +391,20 @@ bool FakeGaia::GetQueryParameter(const std::string& query,
GURL query_url("http://localhost?" + query);
return net::GetValueForKeyInQuery(query_url, key, value);
}
+
+// static
+bool FakeGaia::GetAccessToken(const HttpRequest& request,
+ const char* auth_token_prefix,
+ std::string* access_token) {
+ std::map<std::string, std::string>::const_iterator auth_header_entry =
+ request.headers.find("Authorization");
+ if (auth_header_entry != request.headers.end()) {
+ if (StartsWithASCII(auth_header_entry->second, auth_token_prefix, true)) {
+ *access_token = auth_header_entry->second.substr(
+ strlen(auth_token_prefix));
+ return true;
+ }
+ }
+
+ return false;
+}
« google_apis/gaia/fake_gaia.h ('K') | « google_apis/gaia/fake_gaia.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698