summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-18 17:31:45 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-18 17:31:45 +0000
commit31a7fb0a3f7bec9db975db7b2526dac9624c0dc5 (patch)
treef76e629398c4d67cd735a6e168cc674b5e2ec028
parent2a6c3e512baa6c237861d756d97cecf39e24ad4b (diff)
downloadchromium_src-31a7fb0a3f7bec9db975db7b2526dac9624c0dc5.zip
chromium_src-31a7fb0a3f7bec9db975db7b2526dac9624c0dc5.tar.gz
chromium_src-31a7fb0a3f7bec9db975db7b2526dac9624c0dc5.tar.bz2
Additional OAuth2 tests for ChromeOS
- authentication attempt for invalid OAuth2 refresh token - authentication of an existing user BUG=none TEST=OAuth2.* Review URL: https://codereview.chromium.org/108663008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241581 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/login/oauth2_browsertest.cc260
-rw-r--r--chrome/browser/chromeos/login/saml_browsertest.cc18
-rw-r--r--google_apis/gaia/fake_gaia.cc161
-rw-r--r--google_apis/gaia/fake_gaia.h49
4 files changed, 407 insertions, 81 deletions
diff --git a/chrome/browser/chromeos/login/oauth2_browsertest.cc b/chrome/browser/chromeos/login/oauth2_browsertest.cc
index bbbed3e..953d21c 100644
--- a/chrome/browser/chromeos/login/oauth2_browsertest.cc
+++ b/chrome/browser/chromeos/login/oauth2_browsertest.cc
@@ -3,16 +3,26 @@
// found in the LICENSE file.
#include "base/message_loop/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/login/oauth2_login_manager.h"
#include "chrome/browser/chromeos/login/oauth2_login_manager_factory.h"
#include "chrome/browser/chromeos/login/oobe_base_test.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
#include "content/public/browser/notification_service.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_monster.h"
+#include "net/cookies/cookie_store.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
namespace chromeos {
@@ -20,13 +30,18 @@ namespace {
// Email of owner account for test.
const char kTestAccountId[] = "username@gmail.com";
-
+const char kTestRawAccountId[] = "User.Name";
+const char kTestAccountPassword[] = "fake-password";
const char kTestAuthCode[] = "fake-auth-code";
const char kTestGaiaUberToken[] = "fake-uber-token";
const char kTestAuthLoginAccessToken[] = "fake-access-token";
const char kTestRefreshToken[] = "fake-refresh-token";
+const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie";
+const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie";
const char kTestSessionSIDCookie[] = "fake-session-SID-cookie";
const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie";
+const char kTestSession2SIDCookie[] = "fake-session2-SID-cookie";
+const char kTestSession2LSIDCookie[] = "fake-session2-LSID-cookie";
const char kTestUserinfoToken[] = "fake-userinfo-token";
const char kTestLoginToken[] = "fake-login-token";
const char kTestSyncToken[] = "fake-sync-token";
@@ -40,16 +55,85 @@ class OAuth2Test : public OobeBaseTest {
virtual void SetUpOnMainThread() OVERRIDE {
OobeBaseTest::SetUpOnMainThread();
+ }
+
+ void SetupGaiaServerForNewAccount() {
+ FakeGaia::MergeSessionParams params;
+ params.auth_sid_cookie = kTestAuthSIDCookie;
+ params.auth_lsid_cookie = kTestAuthLSIDCookie;
+ params.auth_code = kTestAuthCode;
+ params.refresh_token = kTestRefreshToken;
+ params.access_token = kTestAuthLoginAccessToken;
+ params.gaia_uber_token = kTestGaiaUberToken;
+ params.session_sid_cookie = kTestSessionSIDCookie;
+ params.session_lsid_cookie = kTestSessionLSIDCookie;
+ fake_gaia_.SetMergeSessionParams(params);
+ SetupGaiaServerWithAccessTokens();
+ }
+
+ void SetupGaiaServerForExistingAccount() {
+ FakeGaia::MergeSessionParams params;
+ params.gaia_uber_token = kTestGaiaUberToken;
+ params.session_sid_cookie = kTestSession2SIDCookie;
+ params.session_lsid_cookie = kTestSession2LSIDCookie;
+ fake_gaia_.SetMergeSessionParams(params);
+ SetupGaiaServerWithAccessTokens();
+ }
+ bool TryToLogin(const std::string& username,
+ const std::string& password) {
+ if (!AddUserTosession(username, password))
+ return false;
+
+ if (const User* active_user = UserManager::Get()->GetActiveUser())
+ return active_user->email() == username;
+
+ return false;
+ }
+
+ User::OAuthTokenStatus GetOAuthStatusFromLocalState(
+ const std::string& user_id) const {
+ PrefService* local_state = g_browser_process->local_state();
+ const DictionaryValue* prefs_oauth_status =
+ local_state->GetDictionary("OAuthTokenStatus");
+ int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
+ if (prefs_oauth_status &&
+ prefs_oauth_status->GetIntegerWithoutPathExpansion(
+ user_id, &oauth_token_status)) {
+ User::OAuthTokenStatus result =
+ static_cast<User::OAuthTokenStatus>(oauth_token_status);
+ return result;
+ }
+ return User::OAUTH_TOKEN_STATUS_UNKNOWN;
+ }
+
+ private:
+ bool AddUserTosession(const std::string& username,
+ const std::string& password) {
+ ExistingUserController* controller =
+ ExistingUserController::current_controller();
+ if (!controller) {
+ ADD_FAILURE();
+ return false;
+ }
+
+ controller->Login(UserContext(username, password, std::string()));
+ content::WindowedNotificationObserver(
+ chrome::NOTIFICATION_SESSION_STARTED,
+ content::NotificationService::AllSources()).Wait();
+ const UserList& logged_users = UserManager::Get()->GetLoggedInUsers();
+ for (UserList::const_iterator it = logged_users.begin();
+ it != logged_users.end(); ++it) {
+ if ((*it)->email() == username)
+ return true;
+ }
+ return false;
+ }
+
+ void SetupGaiaServerWithAccessTokens() {
// Configure OAuth authentication.
GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
- fake_gaia_.SetAuthTokens(kTestAuthCode,
- kTestRefreshToken,
- kTestAuthLoginAccessToken,
- kTestGaiaUberToken,
- kTestSessionSIDCookie,
- kTestSessionLSIDCookie);
// This token satisfies the userinfo.email request from
// DeviceOAuth2TokenService used in token validation.
FakeGaia::AccessTokenInfo userinfo_token_info;
@@ -89,10 +173,68 @@ class OAuth2Test : public OobeBaseTest {
fake_gaia_.IssueOAuthToken(kTestRefreshToken, auth_login_token_info);
}
- private:
DISALLOW_COPY_AND_ASSIGN(OAuth2Test);
};
+class CookieReader : public base::RefCountedThreadSafe<CookieReader> {
+ public:
+ CookieReader() {
+ }
+
+ void ReadCookies(Profile* profile) {
+ context_ = profile->GetRequestContext();
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CookieReader::ReadCookiesOnIOThread,
+ this));
+ runner_ = new content::MessageLoopRunner;
+ runner_->Run();
+ }
+
+ std::string GetCookieValue(const std::string& name) {
+ for (std::vector<net::CanonicalCookie>::const_iterator iter =
+ cookie_list_.begin();
+ iter != cookie_list_.end();
+ ++iter) {
+ if (iter->Name() == name) {
+ return iter->Value();
+ }
+ }
+ return std::string();
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<CookieReader>;
+
+ virtual ~CookieReader() {
+ }
+
+ void ReadCookiesOnIOThread() {
+ context_->GetURLRequestContext()->cookie_store()->GetCookieMonster()->
+ GetAllCookiesAsync(base::Bind(
+ &CookieReader::OnGetAllCookiesOnUIThread,
+ this));
+ }
+
+ void OnGetAllCookiesOnUIThread(const net::CookieList& cookies) {
+ cookie_list_ = cookies;
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&CookieReader::OnCookiesReadyOnUIThread,
+ this));
+ }
+
+ void OnCookiesReadyOnUIThread() {
+ runner_->Quit();
+ }
+
+ scoped_refptr<net::URLRequestContextGetter> context_;
+ net::CookieList cookie_list_;
+ scoped_refptr<content::MessageLoopRunner> runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(CookieReader);
+};
+
class OAuth2LoginManagerStateWaiter : public OAuth2LoginManager::Observer {
public:
explicit OAuth2LoginManagerStateWaiter(Profile* profile)
@@ -146,7 +288,9 @@ class OAuth2LoginManagerStateWaiter : public OAuth2LoginManager::Observer {
DISALLOW_COPY_AND_ASSIGN(OAuth2LoginManagerStateWaiter);
};
-IN_PROC_BROWSER_TEST_F(OAuth2Test, NewUser) {
+// PRE_MergeSession is testing merge session for a new profile.
+IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_PRE_MergeSession) {
+ SetupGaiaServerForNewAccount();
SimulateNetworkOnline();
chromeos::WizardController::SkipPostLoginScreensForTesting();
chromeos::WizardController* wizard_controller =
@@ -157,14 +301,20 @@ IN_PROC_BROWSER_TEST_F(OAuth2Test, NewUser) {
chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
content::NotificationService::AllSources()).Wait();
+ EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
+ User::OAUTH_TOKEN_STATUS_UNKNOWN);
+
// Use capitalized and dotted user name on purpose to make sure
// our email normalization kicks in.
- GetLoginDisplay()->ShowSigninScreenForCreds("User.Name", "password");
+ GetLoginDisplay()->ShowSigninScreenForCreds(kTestRawAccountId,
+ kTestAccountPassword);
content::WindowedNotificationObserver(
chrome::NOTIFICATION_SESSION_STARTED,
content::NotificationService::AllSources()).Wait();
+ Profile* profile = ProfileManager::GetPrimaryUserProfile();
+ // Wait for the session merge to finish.
std::set<OAuth2LoginManager::SessionRestoreState> states;
states.insert(OAuth2LoginManager::SESSION_RESTORE_DONE);
states.insert(OAuth2LoginManager::SESSION_RESTORE_FAILED);
@@ -174,6 +324,96 @@ IN_PROC_BROWSER_TEST_F(OAuth2Test, NewUser) {
merge_session_waiter.WaitForStates(states);
EXPECT_EQ(merge_session_waiter.final_state(),
OAuth2LoginManager::SESSION_RESTORE_DONE);
+
+ // Check for existance of refresh token.
+ ProfileOAuth2TokenService* token_service =
+ ProfileOAuth2TokenServiceFactory::GetForProfile(
+ profile);
+ EXPECT_TRUE(token_service->RefreshTokenIsAvailable(kTestAccountId));
+
+ EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
+ User::OAUTH2_TOKEN_STATUS_VALID);
+
+ scoped_refptr<CookieReader> cookie_reader(new CookieReader());
+ cookie_reader->ReadCookies(profile);
+ EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie);
+ EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie);
+}
+
+// MergeSession test is running merge session process for an existing profile
+// that was generated in PRE_PRE_MergeSession test.
+IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_MergeSession) {
+ SetupGaiaServerForExistingAccount();
+ SimulateNetworkOnline();
+
+ content::WindowedNotificationObserver(
+ chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
+ content::NotificationService::AllSources()).Wait();
+
+ JsExpect("!!document.querySelector('#account-picker')");
+ JsExpect("!!document.querySelector('#pod-row')");
+
+ EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
+ User::OAUTH2_TOKEN_STATUS_VALID);
+
+ EXPECT_TRUE(TryToLogin(kTestAccountId, kTestAccountPassword));
+ Profile* profile = ProfileManager::GetPrimaryUserProfile();
+
+ // Wait for the session merge to finish.
+ std::set<OAuth2LoginManager::SessionRestoreState> states;
+ states.insert(OAuth2LoginManager::SESSION_RESTORE_DONE);
+ states.insert(OAuth2LoginManager::SESSION_RESTORE_FAILED);
+ states.insert(OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED);
+ OAuth2LoginManagerStateWaiter merge_session_waiter(profile);
+ merge_session_waiter.WaitForStates(states);
+ EXPECT_EQ(merge_session_waiter.final_state(),
+ OAuth2LoginManager::SESSION_RESTORE_DONE);
+
+ // Check for existance of refresh token.
+ ProfileOAuth2TokenService* token_service =
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
+ EXPECT_TRUE(token_service->RefreshTokenIsAvailable(kTestAccountId));
+
+ EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
+ User::OAUTH2_TOKEN_STATUS_VALID);
+
+ scoped_refptr<CookieReader> cookie_reader(new CookieReader());
+ cookie_reader->ReadCookies(profile);
+ EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSession2SIDCookie);
+ EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSession2LSIDCookie);
+}
+
+// MergeSession test is attempting to merge session for an existing profile
+// that was generated in PRE_PRE_MergeSession test. This attempt should fail
+// since FakeGaia instance isn't configured to return relevant tokens/cookies.
+IN_PROC_BROWSER_TEST_F(OAuth2Test, MergeSession) {
+ SimulateNetworkOnline();
+
+ content::WindowedNotificationObserver(
+ chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
+ content::NotificationService::AllSources()).Wait();
+
+ JsExpect("!!document.querySelector('#account-picker')");
+ JsExpect("!!document.querySelector('#pod-row')");
+
+ EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
+ User::OAUTH2_TOKEN_STATUS_VALID);
+
+ EXPECT_TRUE(TryToLogin(kTestAccountId, kTestAccountPassword));
+
+ // Wait for the session merge to finish.
+ std::set<OAuth2LoginManager::SessionRestoreState> states;
+ states.insert(OAuth2LoginManager::SESSION_RESTORE_DONE);
+ states.insert(OAuth2LoginManager::SESSION_RESTORE_FAILED);
+ states.insert(OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED);
+ OAuth2LoginManagerStateWaiter merge_session_waiter(
+ ProfileManager::GetPrimaryUserProfile());
+ merge_session_waiter.WaitForStates(states);
+ EXPECT_EQ(merge_session_waiter.final_state(),
+ OAuth2LoginManager::SESSION_RESTORE_FAILED);
+
+ EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
+ User::OAUTH2_TOKEN_STATUS_INVALID);
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml_browsertest.cc b/chrome/browser/chromeos/login/saml_browsertest.cc
index 6b55bce4..91224c6 100644
--- a/chrome/browser/chromeos/login/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml_browsertest.cc
@@ -36,6 +36,8 @@ namespace chromeos {
namespace {
+const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie";
+const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie";
const char kTestAuthCode[] = "fake-auth-code";
const char kTestGaiaUberToken[] = "fake-uber-token";
const char kTestAuthLoginAccessToken[] = "fake-access-token";
@@ -175,12 +177,16 @@ class SamlTest : public InProcessBrowserTest {
}
virtual void SetUpOnMainThread() OVERRIDE {
- fake_gaia_.SetAuthTokens(kTestAuthCode,
- kTestRefreshToken,
- kTestAuthLoginAccessToken,
- kTestGaiaUberToken,
- kTestSessionSIDCookie,
- kTestSessionLSIDCookie);
+ FakeGaia::MergeSessionParams params;
+ params.auth_sid_cookie = kTestAuthSIDCookie;
+ params.auth_lsid_cookie = kTestAuthLSIDCookie;
+ params.auth_code = kTestAuthCode;
+ params.refresh_token = kTestRefreshToken;
+ params.access_token = kTestAuthLoginAccessToken;
+ params.gaia_uber_token = kTestGaiaUberToken;
+ params.session_sid_cookie = kTestSessionSIDCookie;
+ params.session_lsid_cookie = kTestSessionLSIDCookie;
+ fake_gaia_.SetMergeSessionParams(params);
embedded_test_server()->RegisterRequestHandler(
base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc
index 9eddd85..3c1928a 100644
--- a/google_apis/gaia/fake_gaia.cc
+++ b/google_apis/gaia/fake_gaia.cc
@@ -13,6 +13,7 @@
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -21,6 +22,7 @@
#include "base/values.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/url_util.h"
+#include "net/cookies/parsed_cookie.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"
@@ -45,6 +47,52 @@ const base::FilePath::CharType kServiceLogin[] =
const char kAuthHeaderBearer[] = "Bearer ";
const char kAuthHeaderOAuth[] = "OAuth ";
+typedef std::map<std::string, std::string> CookieMap;
+
+// Parses cookie name-value map our of |request|.
+CookieMap GetRequestCookies(const HttpRequest& request) {
+ CookieMap result;
+ std::map<std::string, std::string>::const_iterator iter =
+ request.headers.find("Cookie");
+ if (iter != request.headers.end()) {
+ std::vector<std::string> cookie_nv_pairs;
+ base::SplitString(iter->second, ' ', &cookie_nv_pairs);
+ for(std::vector<std::string>::const_iterator cookie_line =
+ cookie_nv_pairs.begin();
+ cookie_line != cookie_nv_pairs.end();
+ ++cookie_line) {
+ std::vector<std::string> name_value;
+ base::SplitString(*cookie_line, '=', &name_value);
+ if (name_value.size() != 2)
+ continue;
+
+ std::string value = name_value[1];
+ if (value.size() && value[value.size() - 1] == ';')
+ value = value.substr(0, value.size() -1);
+
+ result.insert(std::make_pair(name_value[0], value));
+ }
+ }
+ return result;
+}
+
+// Extracts the |access_token| from authorization header of |request|.
+bool 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;
+}
+
}
FakeGaia::AccessTokenInfo::AccessTokenInfo()
@@ -52,6 +100,12 @@ FakeGaia::AccessTokenInfo::AccessTokenInfo()
FakeGaia::AccessTokenInfo::~AccessTokenInfo() {}
+FakeGaia::MergeSessionParams::MergeSessionParams() {
+}
+
+FakeGaia::MergeSessionParams::~MergeSessionParams() {
+}
+
FakeGaia::FakeGaia() {
base::FilePath source_root_dir;
PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir);
@@ -62,18 +116,9 @@ FakeGaia::FakeGaia() {
FakeGaia::~FakeGaia() {}
-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::SetMergeSessionParams(
+ const MergeSessionParams& params) {
+ merge_session_params_ = params;
}
void FakeGaia::Initialize() {
@@ -117,18 +162,36 @@ void FakeGaia::Initialize() {
void FakeGaia::HandleProgramaticAuth(
const HttpRequest& request,
BasicHttpResponse* http_response) {
+ http_response->set_code(net::HTTP_UNAUTHORIZED);
+ if (merge_session_params_.auth_code.empty()) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ return;
+ }
+
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;
+ }
+
+ CookieMap cookies = GetRequestCookies(request);
+ CookieMap::const_iterator sid_iter = cookies.find("SID");
+ if (sid_iter == cookies.end() ||
+ sid_iter->second != merge_session_params_.auth_sid_cookie) {
+ LOG(ERROR) << "/o/oauth2/programmatic_auth missing SID cookie";
+ return;
+ }
+ CookieMap::const_iterator lsid_iter = cookies.find("LSID");
+ if (lsid_iter == cookies.end() ||
+ lsid_iter->second != merge_session_params_.auth_lsid_cookie) {
+ LOG(ERROR) << "/o/oauth2/programmatic_auth missing LSID cookie";
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;
}
@@ -136,7 +199,7 @@ void FakeGaia::HandleProgramaticAuth(
"Set-Cookie",
base::StringPrintf(
"oauth_code=%s; Path=/o/GetOAuth2Token; Secure; HttpOnly;",
- fake_auth_code_.c_str()));
+ merge_session_params_.auth_code.c_str()));
http_response->set_code(net::HTTP_OK);
http_response->set_content_type("text/html");
}
@@ -150,7 +213,12 @@ void FakeGaia::HandleServiceLogin(const HttpRequest& request,
void FakeGaia::HandleOAuthLogin(const HttpRequest& request,
BasicHttpResponse* http_response) {
- http_response->set_code(net::HTTP_BAD_REQUEST);
+ http_response->set_code(net::HTTP_UNAUTHORIZED);
+ if (merge_session_params_.gaia_uber_token.empty()) {
+ http_response->set_code(net::HTTP_FORBIDDEN);
+ return;
+ }
+
std::string access_token;
if (!GetAccessToken(request, kAuthHeaderOAuth, &access_token)) {
LOG(ERROR) << "/OAuthLogin missing access token in the header";
@@ -169,7 +237,7 @@ void FakeGaia::HandleOAuthLogin(const HttpRequest& request,
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_content(merge_session_params_.gaia_uber_token);
http_response->set_code(net::HTTP_OK);
// Issue GAIA uber token.
} else {
@@ -179,11 +247,16 @@ void FakeGaia::HandleOAuthLogin(const HttpRequest& request,
void FakeGaia::HandleMergeSession(const HttpRequest& request,
BasicHttpResponse* http_response) {
- http_response->set_code(net::HTTP_BAD_REQUEST);
+ http_response->set_code(net::HTTP_UNAUTHORIZED);
+ if (merge_session_params_.session_sid_cookie.empty() ||
+ merge_session_params_.session_lsid_cookie.empty()) {
+ http_response->set_code(net::HTTP_BAD_REQUEST);
+ return;
+ }
std::string uber_token;
if (!GetQueryParameter(request.content, "uberauth", &uber_token) ||
- uber_token != fake_gaia_uber_token_) {
+ uber_token != merge_session_params_.gaia_uber_token) {
LOG(ERROR) << "Missing or invalid 'uberauth' param in /MergeSession call";
return;
}
@@ -203,9 +276,13 @@ void FakeGaia::HandleMergeSession(const HttpRequest& request,
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()));
+ "SID=%s; Path=/; HttpOnly;",
+ merge_session_params_.session_sid_cookie.c_str()));
+ http_response->AddCustomHeader(
+ "Set-Cookie",
+ base::StringPrintf(
+ "LSID=%s; Path=/; HttpOnly;",
+ merge_session_params_.session_lsid_cookie.c_str()));
// TODO(zelidrag): Not used now.
http_response->set_content("OK");
http_response->set_code(net::HTTP_OK);
@@ -229,6 +306,20 @@ void FakeGaia::HandleServiceLoginAuth(const HttpRequest& request,
redirect_url = url.spec();
}
+ if (!merge_session_params_.auth_sid_cookie.empty() &&
+ !merge_session_params_.auth_lsid_cookie.empty()) {
+ http_response->AddCustomHeader(
+ "Set-Cookie",
+ base::StringPrintf(
+ "SID=%s; Path=/; HttpOnly;",
+ merge_session_params_.auth_sid_cookie.c_str()));
+ http_response->AddCustomHeader(
+ "Set-Cookie",
+ base::StringPrintf(
+ "LSID=%s; Path=/; HttpOnly;",
+ merge_session_params_.auth_lsid_cookie.c_str()));
+ }
+
http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
http_response->AddCustomHeader("Location", redirect_url);
}
@@ -260,7 +351,7 @@ void FakeGaia::HandleAuthToken(const HttpRequest& request,
if (grant_type == "authorization_code") {
if (!GetQueryParameter(request.content, "code", &auth_code) ||
- auth_code != fake_auth_code_) {
+ auth_code != merge_session_params_.auth_code) {
http_response->set_code(net::HTTP_BAD_REQUEST);
LOG(ERROR) << "No 'code' param in /o/oauth2/token";
return;
@@ -273,8 +364,10 @@ void FakeGaia::HandleAuthToken(const HttpRequest& request,
}
base::DictionaryValue response_dict;
- response_dict.SetString("refresh_token", fake_refresh_token_);
- response_dict.SetString("access_token", fake_access_token_);
+ response_dict.SetString("refresh_token",
+ merge_session_params_.refresh_token);
+ response_dict.SetString("access_token",
+ merge_session_params_.access_token);
response_dict.SetInteger("expires_in", 3600);
FormatJSONResponse(response_dict, http_response);
} else if (GetQueryParameter(request.content,
@@ -352,7 +445,6 @@ void FakeGaia::HandleIssueToken(const HttpRequest& 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|.
@@ -422,20 +514,3 @@ 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;
-}
diff --git a/google_apis/gaia/fake_gaia.h b/google_apis/gaia/fake_gaia.h
index 6052c2b..ae8c544 100644
--- a/google_apis/gaia/fake_gaia.h
+++ b/google_apis/gaia/fake_gaia.h
@@ -47,16 +47,36 @@ class FakeGaia {
std::string email;
};
+ // Cookies and tokens for /MergeSession call seqeunce.
+ struct MergeSessionParams {
+ MergeSessionParams();
+ ~MergeSessionParams();
+
+ // Values of SID and LSID cookie that are set by
+ std::string auth_sid_cookie;
+ std::string auth_lsid_cookie;
+
+ // auth_code cookie value response for /o/oauth2/programmatic_auth call.
+ std::string auth_code;
+
+ // OAuth2 refresh and access token generated by /o/oauth2/token call
+ // with "...&grant_type=authorization_code".
+ std::string refresh_token;
+ std::string access_token;
+
+ // Uber token response from /OAuthLogin call.
+ std::string gaia_uber_token;
+
+ // Values of SID and LSID cookie generated from /MergeSession call.
+ std::string session_sid_cookie;
+ std::string session_lsid_cookie;
+ };
+
FakeGaia();
~FakeGaia();
// Sets the initial value of tokens and cookies.
- void 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);
+ void SetMergeSessionParams(const MergeSessionParams& params);
// Initializes HTTP request handlers. Should be called after switches
// for tweaking GaiaUrls are in place.
@@ -131,22 +151,7 @@ class FakeGaia {
const std::string& scope_string)
const;
- // Extracts the |access_token| from authorization header of |request|.
- static bool GetAccessToken(const net::test_server::HttpRequest& request,
- const char* auth_token_prefix,
- std::string* access_token);
-
- // auth_code cookie value response for /o/oauth2/programmatic_auth call.
- std::string fake_auth_code_;
-
- // refresh_token field value response for the initial /o/oauth2/token call
- // with ...&grant_type=authorization_code.
- std::string fake_refresh_token_;
- std::string fake_access_token_;
- std::string fake_gaia_uber_token_;
- std::string fake_session_sid_cookie_;
- std::string fake_session_lsid_cookie_;
-
+ MergeSessionParams merge_session_params_;
AccessTokenInfoMap access_token_info_map_;
RequestHandlerMap request_handlers_;
std::string service_login_response_;