summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authordroger <droger@chromium.org>2015-07-16 13:39:16 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-16 20:40:03 +0000
commit6414e43520905218aee5a6e9d5a2914199abd104 (patch)
tree5d84358b9aa80c4902d3a90baf2478cb4bf32dcf /components
parent5009d7d961abcbefa1d86c33b87541c495e4507d (diff)
downloadchromium_src-6414e43520905218aee5a6e9d5a2914199abd104.zip
chromium_src-6414e43520905218aee5a6e9d5a2914199abd104.tar.gz
chromium_src-6414e43520905218aee5a6e9d5a2914199abd104.tar.bz2
Componentize signin_header_helper.h (part 2)
This CL moves the cross-platform logic of the following methods to the signin component: BuildManageAccountsParamsIfExists() BUG=332107 TBR=jochen Review URL: https://codereview.chromium.org/1230583011 Cr-Commit-Position: refs/heads/master@{#339113}
Diffstat (limited to 'components')
-rw-r--r--components/signin/core/browser/signin_header_helper.cc108
-rw-r--r--components/signin/core/browser/signin_header_helper.h45
2 files changed, 153 insertions, 0 deletions
diff --git a/components/signin/core/browser/signin_header_helper.cc b/components/signin/core/browser/signin_header_helper.cc
index d6ac68d..43a2efc 100644
--- a/components/signin/core/browser/signin_header_helper.cc
+++ b/components/signin/core/browser/signin_header_helper.cc
@@ -5,21 +5,33 @@
#include "components/signin/core/browser/signin_header_helper.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/google/core/browser/google_util.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_urls.h"
+#include "net/base/escape.h"
+#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
namespace {
+// Dictionary of fields in a mirror response header.
+typedef std::map<std::string, std::string> MirrorResponseHeaderDictionary;
+
const char kChromeConnectedHeader[] = "X-Chrome-Connected";
+const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts";
+const char kContinueUrlAttrName[] = "continue_url";
+const char kEmailAttrName[] = "email";
const char kEnableAccountConsistencyAttrName[] = "enable_account_consistency";
const char kGaiaIdAttrName[] = "id";
const char kProfileModeAttrName[] = "mode";
+const char kIsSameTabAttrName[] = "is_same_tab";
+const char kIsSamlAttrName[] = "is_saml";
+const char kServiceTypeAttrName[] = "action";
bool IsDriveOrigin(const GURL& url) {
if (!url.SchemeIsCryptographic())
@@ -30,10 +42,89 @@ bool IsDriveOrigin(const GURL& url) {
return url == kGoogleDriveURL || url == kGoogleDocsURL;
}
+// Determines the service type that has been passed from GAIA in the header.
+signin::GAIAServiceType GetGAIAServiceTypeFromHeader(
+ const std::string& header_value) {
+ if (header_value == "SIGNOUT")
+ return signin::GAIA_SERVICE_TYPE_SIGNOUT;
+ else if (header_value == "INCOGNITO")
+ return signin::GAIA_SERVICE_TYPE_INCOGNITO;
+ else if (header_value == "ADDSESSION")
+ return signin::GAIA_SERVICE_TYPE_ADDSESSION;
+ else if (header_value == "REAUTH")
+ return signin::GAIA_SERVICE_TYPE_REAUTH;
+ else if (header_value == "SIGNUP")
+ return signin::GAIA_SERVICE_TYPE_SIGNUP;
+ else if (header_value == "DEFAULT")
+ return signin::GAIA_SERVICE_TYPE_DEFAULT;
+ else
+ return signin::GAIA_SERVICE_TYPE_NONE;
+}
+
+// Parses the mirror response header. Its expected format is
+// "key1=value1,key2=value2,...".
+MirrorResponseHeaderDictionary ParseMirrorResponseHeader(
+ const std::string& header_value) {
+ MirrorResponseHeaderDictionary dictionary;
+ for (const base::StringPiece& field :
+ base::SplitStringPiece(header_value, ",", base::KEEP_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY)) {
+ size_t delim = field.find_first_of('=');
+ if (delim == std::string::npos) {
+ DLOG(WARNING) << "Unexpected GAIA header field '" << field << "'.";
+ continue;
+ }
+ dictionary[field.substr(0, delim).as_string()] =
+ net::UnescapeURLComponent(field.substr(delim + 1).as_string(),
+ net::UnescapeRule::URL_SPECIAL_CHARS);
+ }
+ return dictionary;
+}
+
+// Returns the parameters contained in the X-Chrome-Manage-Accounts response
+// header.
+signin::ManageAccountsParams BuildManageAccountsParams(
+ const std::string& header_value) {
+ signin::ManageAccountsParams params;
+ MirrorResponseHeaderDictionary header_dictionary =
+ ParseMirrorResponseHeader(header_value);
+ MirrorResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
+ for (; it != header_dictionary.end(); ++it) {
+ const std::string key_name(it->first);
+ if (key_name == kServiceTypeAttrName) {
+ params.service_type =
+ GetGAIAServiceTypeFromHeader(header_dictionary[kServiceTypeAttrName]);
+ } else if (key_name == kEmailAttrName) {
+ params.email = header_dictionary[kEmailAttrName];
+ } else if (key_name == kIsSamlAttrName) {
+ params.is_saml = header_dictionary[kIsSamlAttrName] == "true";
+ } else if (key_name == kContinueUrlAttrName) {
+ params.continue_url = header_dictionary[kContinueUrlAttrName];
+ } else if (key_name == kIsSameTabAttrName) {
+ params.is_same_tab = header_dictionary[kIsSameTabAttrName] == "true";
+ } else {
+ DLOG(WARNING) << "Unexpected GAIA header attribute '" << key_name << "'.";
+ }
+ }
+ return params;
+}
+
} // namespace
namespace signin {
+ManageAccountsParams::ManageAccountsParams()
+ : service_type(GAIA_SERVICE_TYPE_NONE),
+ email(""),
+ is_saml(false),
+ continue_url(""),
+ is_same_tab(false) {
+#if !defined(OS_IOS)
+ child_id = 0;
+ route_id = 0;
+#endif // !defined(OS_IOS)
+}
+
bool SettingsAllowSigninCookies(
content_settings::CookieSettings* cookie_settings) {
GURL gaia_url = GaiaUrls::GetInstance()->gaia_url();
@@ -89,4 +180,21 @@ bool AppendMirrorRequestHeaderIfPossible(
return true;
}
+ManageAccountsParams BuildManageAccountsParamsIfExists(net::URLRequest* request,
+ bool is_off_the_record) {
+ ManageAccountsParams empty_params;
+ empty_params.service_type = GAIA_SERVICE_TYPE_NONE;
+ if (!gaia::IsGaiaSignonRealm(request->url().GetOrigin()))
+ return empty_params;
+
+ std::string header_value;
+ if (!request->response_headers()->GetNormalizedHeader(
+ kChromeManageAccountsHeader, &header_value)) {
+ return empty_params;
+ }
+
+ DCHECK(switches::IsEnableAccountConsistency() && !is_off_the_record);
+ return BuildManageAccountsParams(header_value);
+}
+
} // namespace signin
diff --git a/components/signin/core/browser/signin_header_helper.h b/components/signin/core/browser/signin_header_helper.h
index 404efaf..a03b20b 100644
--- a/components/signin/core/browser/signin_header_helper.h
+++ b/components/signin/core/browser/signin_header_helper.h
@@ -28,6 +28,44 @@ enum ProfileMode {
PROFILE_MODE_ADD_ACCOUNT_DISABLED = 1 << 1
};
+// The ServiceType specified by GAIA in the response header accompanying the 204
+// response. This indicates the action Chrome is supposed to lead the user to
+// perform.
+enum GAIAServiceType {
+ GAIA_SERVICE_TYPE_NONE = 0, // No GAIA response header.
+ GAIA_SERVICE_TYPE_SIGNOUT, // Logout all existing sessions.
+ GAIA_SERVICE_TYPE_INCOGNITO, // Open an incognito tab.
+ GAIA_SERVICE_TYPE_ADDSESSION, // Add a secondary account.
+ GAIA_SERVICE_TYPE_REAUTH, // Re-authenticate an account.
+ GAIA_SERVICE_TYPE_SIGNUP, // Create a new account.
+ GAIA_SERVICE_TYPE_DEFAULT, // All other cases.
+};
+
+// Struct describing the paramters received in the manage account header.
+struct ManageAccountsParams {
+ // The requested service type such as "ADDSESSION".
+ GAIAServiceType service_type;
+ // The prefilled email.
+ std::string email;
+ // Whether |email| is a saml account.
+ bool is_saml;
+ // The continue URL after the requested service is completed successfully.
+ // Defaults to the current URL if empty.
+ std::string continue_url;
+ // Whether the continue URL should be loaded in the same tab.
+ bool is_same_tab;
+
+// iOS has no notion of route and child IDs.
+#if !defined(OS_IOS)
+ // The child id associated with the web content of the request.
+ int child_id;
+ // The route id associated with the web content of the request.
+ int route_id;
+#endif // !defined(OS_IOS)
+
+ ManageAccountsParams();
+};
+
// Returns true if signin cookies are allowed.
bool SettingsAllowSigninCookies(
content_settings::CookieSettings* cookie_settings);
@@ -42,6 +80,13 @@ bool AppendMirrorRequestHeaderIfPossible(
content_settings::CookieSettings* cookie_settings,
int profile_mode_mask);
+// Returns the parameters contained in the X-Chrome-Manage-Accounts response
+// header.
+// If the request does not have a response header or if the header contains
+// garbage, then |service_type| is set to |GAIA_SERVICE_TYPE_NONE|.
+ManageAccountsParams BuildManageAccountsParamsIfExists(net::URLRequest* request,
+ bool is_off_the_record);
+
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_HEADER_HELPER_H_