diff options
author | droger <droger@chromium.org> | 2015-07-16 13:39:16 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-16 20:40:03 +0000 |
commit | 6414e43520905218aee5a6e9d5a2914199abd104 (patch) | |
tree | 5d84358b9aa80c4902d3a90baf2478cb4bf32dcf /components | |
parent | 5009d7d961abcbefa1d86c33b87541c495e4507d (diff) | |
download | chromium_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.cc | 108 | ||||
-rw-r--r-- | components/signin/core/browser/signin_header_helper.h | 45 |
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_ |