Index: chrome/common/net/gaia/gaia_authenticator.cc |
diff --git a/chrome/common/net/gaia/gaia_authenticator.cc b/chrome/common/net/gaia/gaia_authenticator.cc |
deleted file mode 100644 |
index af12b7a1b97a277041fcd72f8078195ffefb29a2..0000000000000000000000000000000000000000 |
--- a/chrome/common/net/gaia/gaia_authenticator.cc |
+++ /dev/null |
@@ -1,400 +0,0 @@ |
-// Copyright (c) 2012 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 "chrome/common/net/gaia/gaia_authenticator.h" |
- |
-#include <string> |
-#include <utility> |
-#include <vector> |
- |
-#include "base/basictypes.h" |
-#include "base/port.h" |
-#include "base/string_split.h" |
-#include "googleurl/src/gurl.h" |
-#include "net/base/escape.h" |
-#include "net/http/http_status_code.h" |
- |
-using std::pair; |
-using std::string; |
-using std::vector; |
- |
-namespace gaia { |
- |
-static const char kGaiaV1IssueAuthTokenPath[] = "/accounts/IssueAuthToken"; |
- |
-static const char kGetUserInfoPath[] = "/accounts/GetUserInfo"; |
- |
-GaiaAuthenticator::AuthResults::AuthResults() : auth_error(None) {} |
- |
-GaiaAuthenticator::AuthResults::AuthResults(const AuthResults& other) |
- : email(other.email), |
- password(other.password), |
- sid(other.sid), |
- lsid(other.lsid), |
- auth_token(other.auth_token), |
- primary_email(other.primary_email), |
- error_msg(other.error_msg), |
- auth_error(other.auth_error), |
- auth_error_url(other.auth_error_url), |
- captcha_token(other.captcha_token), |
- captcha_url(other.captcha_url) { |
-} |
- |
-GaiaAuthenticator::AuthResults::~AuthResults() {} |
- |
-GaiaAuthenticator::AuthParams::AuthParams() : authenticator(NULL), |
- request_id(0) {} |
- |
-GaiaAuthenticator::AuthParams::~AuthParams() {} |
- |
-// Sole constructor with initializers for all fields. |
-GaiaAuthenticator::GaiaAuthenticator(const string& user_agent, |
- const string& service_id, |
- const string& gaia_url) |
- : user_agent_(user_agent), |
- service_id_(service_id), |
- gaia_url_(gaia_url), |
- request_count_(0), |
- delay_(0), |
- next_allowed_auth_attempt_time_(0), |
- early_auth_attempt_count_(0), |
- message_loop_(NULL) { |
-} |
- |
-GaiaAuthenticator::~GaiaAuthenticator() { |
-} |
- |
-// mutex_ must be entered before calling this function. |
-GaiaAuthenticator::AuthParams GaiaAuthenticator::MakeParams( |
- const string& user_name, |
- const string& password, |
- const string& captcha_token, |
- const string& captcha_value) { |
- AuthParams params; |
- params.request_id = ++request_count_; |
- params.email = user_name; |
- params.password = password; |
- params.captcha_token = captcha_token; |
- params.captcha_value = captcha_value; |
- params.authenticator = this; |
- return params; |
-} |
- |
-bool GaiaAuthenticator::Authenticate(const string& user_name, |
- const string& password, |
- const string& captcha_token, |
- const string& captcha_value) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- |
- AuthParams const params = |
- MakeParams(user_name, password, captcha_token, captcha_value); |
- return AuthenticateImpl(params); |
-} |
- |
-bool GaiaAuthenticator::AuthenticateWithLsid(const string& lsid) { |
- auth_results_.lsid = lsid; |
- // We need to lookup the email associated with this LSID cookie in order to |
- // update |auth_results_| with the correct values. |
- if (LookupEmail(&auth_results_)) { |
- auth_results_.email = auth_results_.primary_email; |
- return IssueAuthToken(&auth_results_, service_id_); |
- } |
- return false; |
-} |
- |
-bool GaiaAuthenticator::AuthenticateImpl(const AuthParams& params) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- AuthResults results; |
- const bool succeeded = AuthenticateImpl(params, &results); |
- return succeeded; |
-} |
- |
-// This method makes an HTTP request to the Gaia server, and calls other |
-// methods to help parse the response. If authentication succeeded, then |
-// Gaia-issued cookies are available in the respective variables; if |
-// authentication failed, then the exact error is available as an enum. If the |
-// client wishes to save the credentials, the last parameter must be true. |
-// If a subsequent request is made with fresh credentials, the saved credentials |
-// are wiped out; any subsequent request to the zero-parameter overload of this |
-// method preserves the saved credentials. |
-bool GaiaAuthenticator::AuthenticateImpl(const AuthParams& params, |
- AuthResults* results) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- results->auth_error = ConnectionUnavailable; |
- results->email = params.email.data(); |
- results->password = params.password; |
- |
- // The aim of this code is to start failing requests if due to a logic error |
- // in the program we're hammering GAIA. |
-#if defined(OS_WIN) |
- __time32_t now = _time32(0); |
-#else // defined(OS_WIN) |
- time_t now = time(0); |
-#endif // defined(OS_WIN) |
- |
- if (now > next_allowed_auth_attempt_time_) { |
- next_allowed_auth_attempt_time_ = now + 1; |
- // If we're more than 2 minutes past the allowed time we reset the early |
- // attempt count. |
- if (now - next_allowed_auth_attempt_time_ > 2 * 60) { |
- delay_ = 1; |
- early_auth_attempt_count_ = 0; |
- } |
- } else { |
- ++early_auth_attempt_count_; |
- // Allow 3 attempts, but then limit. |
- if (early_auth_attempt_count_ > 3) { |
- delay_ = GetBackoffDelaySeconds(delay_); |
- next_allowed_auth_attempt_time_ = now + delay_; |
- return false; |
- } |
- } |
- |
- return PerformGaiaRequest(params, results); |
-} |
- |
-bool GaiaAuthenticator::PerformGaiaRequest(const AuthParams& params, |
- AuthResults* results) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- GURL gaia_auth_url(gaia_url_); |
- |
- string post_body; |
- post_body += "Email=" + net::EscapeUrlEncodedData(params.email, true); |
- post_body += "&Passwd=" + net::EscapeUrlEncodedData(params.password, true); |
- post_body += "&source=" + net::EscapeUrlEncodedData(user_agent_, true); |
- post_body += "&service=" + service_id_; |
- if (!params.captcha_token.empty() && !params.captcha_value.empty()) { |
- post_body += "&logintoken=" + |
- net::EscapeUrlEncodedData(params.captcha_token, true); |
- post_body += "&logincaptcha=" + |
- net::EscapeUrlEncodedData(params.captcha_value, true); |
- } |
- post_body += "&PersistentCookie=true"; |
- // We set it to GOOGLE (and not HOSTED or HOSTED_OR_GOOGLE) because we only |
- // allow consumer logins. |
- post_body += "&accountType=GOOGLE"; |
- |
- string message_text; |
- unsigned long server_response_code; |
- if (!Post(gaia_auth_url, post_body, &server_response_code, &message_text)) { |
- results->auth_error = ConnectionUnavailable; |
- return false; |
- } |
- |
- // Parse reply in two different ways, depending on if request failed or |
- // succeeded. |
- if (net::HTTP_FORBIDDEN == server_response_code) { |
- ExtractAuthErrorFrom(message_text, results); |
- return false; |
- } else if (net::HTTP_OK == server_response_code) { |
- ExtractTokensFrom(message_text, results); |
- if (!IssueAuthToken(results, service_id_)) { |
- return false; |
- } |
- |
- return LookupEmail(results); |
- } else { |
- results->auth_error = Unknown; |
- return false; |
- } |
-} |
- |
-bool GaiaAuthenticator::Post(const GURL& url, |
- const std::string& post_body, |
- unsigned long* response_code, |
- std::string* response_body) { |
- return false; |
-} |
- |
-bool GaiaAuthenticator::LookupEmail(AuthResults* results) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- // Use the provided Gaia server, but change the path to what V1 expects. |
- GURL url(gaia_url_); // Gaia server. |
- GURL::Replacements repl; |
- // Needs to stay in scope till GURL is out of scope. |
- string path(kGetUserInfoPath); |
- repl.SetPathStr(path); |
- url = url.ReplaceComponents(repl); |
- |
- string post_body; |
- post_body += "LSID="; |
- post_body += net::EscapeUrlEncodedData(results->lsid, true); |
- |
- unsigned long server_response_code; |
- string message_text; |
- if (!Post(url, post_body, &server_response_code, &message_text)) { |
- return false; |
- } |
- |
- // Check if we received a valid AuthToken; if not, ignore it. |
- if (net::HTTP_FORBIDDEN == server_response_code) { |
- // Server says we're not authenticated. |
- ExtractAuthErrorFrom(message_text, results); |
- return false; |
- } else if (net::HTTP_OK == server_response_code) { |
- typedef vector<pair<string, string> > Tokens; |
- Tokens tokens; |
- base::SplitStringIntoKeyValuePairs(message_text, '=', '\n', &tokens); |
- for (Tokens::iterator i = tokens.begin(); i != tokens.end(); ++i) { |
- if ("accountType" == i->first) { |
- // We never authenticate an email as a hosted account. |
- DCHECK_EQ("GOOGLE", i->second); |
- } else if ("email" == i->first) { |
- results->primary_email = i->second; |
- } |
- } |
- return true; |
- } |
- return false; |
-} |
- |
-int GaiaAuthenticator::GetBackoffDelaySeconds(int current_backoff_delay) { |
- NOTREACHED(); |
- return current_backoff_delay; |
-} |
- |
-// We need to call this explicitly when we need to obtain a long-lived session |
-// token. |
-bool GaiaAuthenticator::IssueAuthToken(AuthResults* results, |
- const string& service_id) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- // Use the provided Gaia server, but change the path to what V1 expects. |
- GURL url(gaia_url_); // Gaia server. |
- GURL::Replacements repl; |
- // Needs to stay in scope till GURL is out of scope. |
- string path(kGaiaV1IssueAuthTokenPath); |
- repl.SetPathStr(path); |
- url = url.ReplaceComponents(repl); |
- |
- string post_body; |
- post_body += "LSID="; |
- post_body += net::EscapeUrlEncodedData(results->lsid, true); |
- post_body += "&service=" + service_id; |
- post_body += "&Session=true"; |
- |
- unsigned long server_response_code; |
- string message_text; |
- if (!Post(url, post_body, &server_response_code, &message_text)) { |
- return false; |
- } |
- |
- // Check if we received a valid AuthToken; if not, ignore it. |
- if (net::HTTP_FORBIDDEN == server_response_code) { |
- // Server says we're not authenticated. |
- ExtractAuthErrorFrom(message_text, results); |
- return false; |
- } else if (net::HTTP_OK == server_response_code) { |
- // Note that the format of message_text is different from what is returned |
- // in the first request, or to the sole request that is made to Gaia V2. |
- // Specifically, the entire string is the AuthToken, and looks like: |
- // "<token>" rather than "AuthToken=<token>". Thus, we need not use |
- // ExtractTokensFrom(...), but simply assign the token. |
- int last_index = message_text.length() - 1; |
- if ('\n' == message_text[last_index]) |
- message_text.erase(last_index); |
- results->auth_token = message_text; |
- return true; |
- } |
- return false; |
-} |
- |
-// Helper method that extracts tokens from a successful reply, and saves them |
-// in the right fields. |
-void GaiaAuthenticator::ExtractTokensFrom(const string& response, |
- AuthResults* results) { |
- vector<pair<string, string> > tokens; |
- base::SplitStringIntoKeyValuePairs(response, '=', '\n', &tokens); |
- for (vector<pair<string, string> >::iterator i = tokens.begin(); |
- i != tokens.end(); ++i) { |
- if (i->first == "SID") { |
- results->sid = i->second; |
- } else if (i->first == "LSID") { |
- results->lsid = i->second; |
- } else if (i->first == "Auth") { |
- results->auth_token = i->second; |
- } |
- } |
-} |
- |
-// Helper method that extracts tokens from a failure response, and saves them |
-// in the right fields. |
-void GaiaAuthenticator::ExtractAuthErrorFrom(const string& response, |
- AuthResults* results) { |
- vector<pair<string, string> > tokens; |
- base::SplitStringIntoKeyValuePairs(response, '=', '\n', &tokens); |
- for (vector<pair<string, string> >::iterator i = tokens.begin(); |
- i != tokens.end(); ++i) { |
- if (i->first == "Error") { |
- results->error_msg = i->second; |
- } else if (i->first == "Url") { |
- results->auth_error_url = i->second; |
- } else if (i->first == "CaptchaToken") { |
- results->captcha_token = i->second; |
- } else if (i->first == "CaptchaUrl") { |
- results->captcha_url = i->second; |
- } |
- } |
- |
- // Convert string error messages to enum values. Each case has two different |
- // strings; the first one is the most current and the second one is |
- // deprecated, but available. |
- const string& error_msg = results->error_msg; |
- if (error_msg == "BadAuthentication" || error_msg == "badauth") { |
- results->auth_error = BadAuthentication; |
- } else if (error_msg == "NotVerified" || error_msg == "nv") { |
- results->auth_error = NotVerified; |
- } else if (error_msg == "TermsNotAgreed" || error_msg == "tna") { |
- results->auth_error = TermsNotAgreed; |
- } else if (error_msg == "Unknown" || error_msg == "unknown") { |
- results->auth_error = Unknown; |
- } else if (error_msg == "AccountDeleted" || error_msg == "adel") { |
- results->auth_error = AccountDeleted; |
- } else if (error_msg == "AccountDisabled" || error_msg == "adis") { |
- results->auth_error = AccountDisabled; |
- } else if (error_msg == "CaptchaRequired" || error_msg == "cr") { |
- results->auth_error = CaptchaRequired; |
- } else if (error_msg == "ServiceUnavailable" || error_msg == "ire") { |
- results->auth_error = ServiceUnavailable; |
- } |
-} |
- |
-// Reset all stored credentials, perhaps in preparation for letting a different |
-// user sign in. |
-void GaiaAuthenticator::ResetCredentials() { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- AuthResults blank; |
- auth_results_ = blank; |
-} |
- |
-void GaiaAuthenticator::SetUsernamePassword(const string& username, |
- const string& password) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- auth_results_.password = password; |
- auth_results_.email = username; |
-} |
- |
-void GaiaAuthenticator::SetUsername(const string& username) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- auth_results_.email = username; |
-} |
- |
-void GaiaAuthenticator::RenewAuthToken(const string& auth_token) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- DCHECK(!this->auth_token().empty()); |
- auth_results_.auth_token = auth_token; |
-} |
-void GaiaAuthenticator::SetAuthToken(const string& auth_token) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- auth_results_.auth_token = auth_token; |
-} |
- |
-bool GaiaAuthenticator::Authenticate(const string& user_name, |
- const string& password) { |
- DCHECK_EQ(MessageLoop::current(), message_loop_); |
- const string empty; |
- return Authenticate(user_name, password, empty, |
- empty); |
-} |
- |
-} // namespace gaia |