OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/signin/core/browser/signin_header_helper.h" | 5 #include "components/signin/core/browser/signin_header_helper.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/string_split.h" | 11 #include "base/strings/string_split.h" |
12 #include "base/strings/string_util.h" | |
12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
14 #include "components/content_settings/core/browser/cookie_settings.h" | 15 #include "components/content_settings/core/browser/cookie_settings.h" |
15 #include "components/google/core/browser/google_util.h" | 16 #include "components/google/core/browser/google_util.h" |
16 #include "components/signin/core/common/profile_management_switches.h" | 17 #include "components/signin/core/common/profile_management_switches.h" |
17 #include "google_apis/gaia/gaia_auth_util.h" | 18 #include "google_apis/gaia/gaia_auth_util.h" |
18 #include "google_apis/gaia/gaia_urls.h" | 19 #include "google_apis/gaia/gaia_urls.h" |
19 #include "net/base/escape.h" | 20 #include "net/base/escape.h" |
20 #include "net/http/http_response_headers.h" | 21 #include "net/http/http_response_headers.h" |
21 #include "net/url_request/url_request.h" | 22 #include "net/url_request/url_request.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
38 | 39 |
39 bool IsDriveOrigin(const GURL& url) { | 40 bool IsDriveOrigin(const GURL& url) { |
40 if (!url.SchemeIsCryptographic()) | 41 if (!url.SchemeIsCryptographic()) |
41 return false; | 42 return false; |
42 | 43 |
43 const GURL kGoogleDriveURL("https://drive.google.com"); | 44 const GURL kGoogleDriveURL("https://drive.google.com"); |
44 const GURL kGoogleDocsURL("https://docs.google.com"); | 45 const GURL kGoogleDocsURL("https://docs.google.com"); |
45 return url == kGoogleDriveURL || url == kGoogleDocsURL; | 46 return url == kGoogleDriveURL || url == kGoogleDocsURL; |
46 } | 47 } |
47 | 48 |
49 bool IsUrlEligibleToIncludeGaiaId(const GURL& url, bool is_header_request) { | |
50 if (is_header_request) { | |
51 // GAIA Id is only necessary for Drive. Don't set it otherwise. | |
52 return IsDriveOrigin(url); | |
battre
2016/09/20 09:01:55
Just to be sure: I think you are passing the url h
bzanotti
2016/09/20 14:49:28
That's a good point, fixed in the new CL.
| |
53 } | |
54 | |
55 // Cookie requests don't have the granularity to only include the GAIA Id for | |
56 // Drive origin. Set it on all google.com instead. | |
57 if (!url.SchemeIsCryptographic()) | |
58 return false; | |
59 | |
60 const GURL kGoogleDotComURL("https://google.com"); | |
61 return url == kGoogleDotComURL; | |
battre
2016/09/20 09:01:55
I think this would be false for https://www.google
bzanotti
2016/09/20 14:49:28
I cheated a little bit here, because I know that t
| |
62 } | |
63 | |
48 // Determines the service type that has been passed from GAIA in the header. | 64 // Determines the service type that has been passed from GAIA in the header. |
49 signin::GAIAServiceType GetGAIAServiceTypeFromHeader( | 65 signin::GAIAServiceType GetGAIAServiceTypeFromHeader( |
50 const std::string& header_value) { | 66 const std::string& header_value) { |
51 if (header_value == "SIGNOUT") | 67 if (header_value == "SIGNOUT") |
52 return signin::GAIA_SERVICE_TYPE_SIGNOUT; | 68 return signin::GAIA_SERVICE_TYPE_SIGNOUT; |
53 else if (header_value == "INCOGNITO") | 69 else if (header_value == "INCOGNITO") |
54 return signin::GAIA_SERVICE_TYPE_INCOGNITO; | 70 return signin::GAIA_SERVICE_TYPE_INCOGNITO; |
55 else if (header_value == "ADDSESSION") | 71 else if (header_value == "ADDSESSION") |
56 return signin::GAIA_SERVICE_TYPE_ADDSESSION; | 72 return signin::GAIA_SERVICE_TYPE_ADDSESSION; |
57 else if (header_value == "REAUTH") | 73 else if (header_value == "REAUTH") |
(...skipping 21 matching lines...) Expand all Loading... | |
79 } | 95 } |
80 dictionary[field.substr(0, delim).as_string()] = net::UnescapeURLComponent( | 96 dictionary[field.substr(0, delim).as_string()] = net::UnescapeURLComponent( |
81 field.substr(delim + 1).as_string(), | 97 field.substr(delim + 1).as_string(), |
82 net::UnescapeRule::PATH_SEPARATORS | | 98 net::UnescapeRule::PATH_SEPARATORS | |
83 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS); | 99 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS); |
84 } | 100 } |
85 return dictionary; | 101 return dictionary; |
86 } | 102 } |
87 | 103 |
88 std::string BuildMirrorRequestIfPossible( | 104 std::string BuildMirrorRequestIfPossible( |
89 const char* pattern, | 105 bool is_header_request, |
90 const GURL& url, | 106 const GURL& url, |
91 const std::string& account_id, | 107 const std::string& account_id, |
92 const content_settings::CookieSettings* cookie_settings, | 108 const content_settings::CookieSettings* cookie_settings, |
93 int profile_mode_mask) { | 109 int profile_mode_mask) { |
94 if (account_id.empty()) | 110 if (account_id.empty()) |
95 return std::string(); | 111 return std::string(); |
96 | 112 |
97 // If signin cookies are not allowed, don't add the header. | 113 // If signin cookies are not allowed, don't add the header. |
98 if (!signin::SettingsAllowSigninCookies(cookie_settings)) { | 114 if (!signin::SettingsAllowSigninCookies(cookie_settings)) { |
99 return std::string(); | 115 return std::string(); |
100 } | 116 } |
101 | 117 |
102 // Check if url is elligible for the header. | 118 // Check if url is elligible for the header. |
103 if (!signin::IsUrlEligibleForXChromeConnectedHeader(url)) | 119 if (!signin::IsUrlEligibleForXChromeConnectedHeader(url)) |
104 return std::string(); | 120 return std::string(); |
105 | 121 |
106 return base::StringPrintf( | 122 std::vector<std::string> parts; |
107 pattern, kGaiaIdAttrName, account_id.c_str(), kProfileModeAttrName, | 123 if (IsUrlEligibleToIncludeGaiaId(url, is_header_request)) { |
108 base::IntToString(profile_mode_mask).c_str(), | 124 // Only google.com requires the GAIA ID, don't send it to other domains. |
battre
2016/09/20 09:01:55
I think this is inconsistent with sending it to dr
bzanotti
2016/09/20 14:49:28
Correct, I forgot to update the comment.
| |
109 kEnableAccountConsistencyAttrName, | 125 parts.push_back( |
110 switches::IsEnableAccountConsistency() ? "true" : "false"); | 126 base::StringPrintf("%s=%s", kGaiaIdAttrName, account_id.c_str())); |
127 } | |
128 parts.push_back( | |
129 base::StringPrintf("%s=%s", kProfileModeAttrName, | |
130 base::IntToString(profile_mode_mask).c_str())); | |
131 parts.push_back(base::StringPrintf( | |
132 "%s=%s", kEnableAccountConsistencyAttrName, | |
133 switches::IsEnableAccountConsistency() ? "true" : "false")); | |
134 | |
135 return base::JoinString(parts, is_header_request ? "," : ":"); | |
111 } | 136 } |
112 | 137 |
113 } // namespace | 138 } // namespace |
114 | 139 |
115 namespace signin { | 140 namespace signin { |
116 | 141 |
117 extern const char kChromeConnectedHeader[] = "X-Chrome-Connected"; | 142 extern const char kChromeConnectedHeader[] = "X-Chrome-Connected"; |
118 | 143 |
119 ManageAccountsParams::ManageAccountsParams() | 144 ManageAccountsParams::ManageAccountsParams() |
120 : service_type(GAIA_SERVICE_TYPE_NONE), | 145 : service_type(GAIA_SERVICE_TYPE_NONE), |
(...skipping 17 matching lines...) Expand all Loading... | |
138 return cookie_settings && | 163 return cookie_settings && |
139 cookie_settings->IsSettingCookieAllowed(gaia_url, gaia_url) && | 164 cookie_settings->IsSettingCookieAllowed(gaia_url, gaia_url) && |
140 cookie_settings->IsSettingCookieAllowed(google_url, google_url); | 165 cookie_settings->IsSettingCookieAllowed(google_url, google_url); |
141 } | 166 } |
142 | 167 |
143 std::string BuildMirrorRequestCookieIfPossible( | 168 std::string BuildMirrorRequestCookieIfPossible( |
144 const GURL& url, | 169 const GURL& url, |
145 const std::string& account_id, | 170 const std::string& account_id, |
146 const content_settings::CookieSettings* cookie_settings, | 171 const content_settings::CookieSettings* cookie_settings, |
147 int profile_mode_mask) { | 172 int profile_mode_mask) { |
148 return BuildMirrorRequestIfPossible("%s=%s:%s=%s:%s=%s", url, account_id, | 173 return BuildMirrorRequestIfPossible(false /* is_header_request */, url, |
149 cookie_settings, profile_mode_mask); | 174 account_id, cookie_settings, |
175 profile_mode_mask); | |
176 } | |
177 | |
178 bool AppendOrRemoveMirrorRequestHeaderIfPossible( | |
179 net::URLRequest* request, | |
180 const GURL& redirect_url, | |
181 const std::string& account_id, | |
182 const content_settings::CookieSettings* cookie_settings, | |
183 int profile_mode_mask) { | |
184 const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url; | |
185 std::string header_value = BuildMirrorRequestIfPossible( | |
186 true /* is_header_request */, url, account_id, cookie_settings, | |
187 profile_mode_mask); | |
188 if (header_value.empty()) { | |
189 // If the request is being redirected, and it has the x-chrome-connected | |
190 // header, and current url is a Google URL, and the redirected one is not, | |
191 // remove the header. | |
192 if (!redirect_url.is_empty() && | |
193 request->extra_request_headers().HasHeader( | |
194 signin::kChromeConnectedHeader) && | |
195 signin::IsUrlEligibleForXChromeConnectedHeader(request->url()) && | |
196 !signin::IsUrlEligibleForXChromeConnectedHeader(redirect_url)) { | |
197 request->RemoveRequestHeaderByName(signin::kChromeConnectedHeader); | |
198 } | |
199 return false; | |
150 } | 200 } |
151 | 201 request->SetExtraRequestHeaderByName(kChromeConnectedHeader, header_value, |
152 bool AppendOrRemoveMirrorRequestHeaderIfPossible( | 202 false); |
153 net::URLRequest* request, | 203 return true; |
154 const GURL& redirect_url, | |
155 const std::string& account_id, | |
156 const content_settings::CookieSettings* cookie_settings, | |
157 int profile_mode_mask) { | |
158 const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url; | |
159 std::string header_value = | |
160 BuildMirrorRequestIfPossible("%s=%s,%s=%s,%s=%s", url, account_id, | |
161 cookie_settings, profile_mode_mask); | |
162 if (header_value.empty()) { | |
163 // If the request is being redirected, and it has the x-chrome-connected | |
164 // header, and current url is a Google URL, and the redirected one is not, | |
165 // remove the header. | |
166 if (!redirect_url.is_empty() && | |
167 request->extra_request_headers().HasHeader( | |
168 signin::kChromeConnectedHeader) && | |
169 signin::IsUrlEligibleForXChromeConnectedHeader(request->url()) && | |
170 !signin::IsUrlEligibleForXChromeConnectedHeader(redirect_url)) { | |
171 request->RemoveRequestHeaderByName(signin::kChromeConnectedHeader); | |
172 } | |
173 return false; | |
174 } | |
175 request->SetExtraRequestHeaderByName(kChromeConnectedHeader, header_value, | |
176 false); | |
177 return true; | |
178 } | 204 } |
179 | 205 |
180 ManageAccountsParams BuildManageAccountsParams( | 206 ManageAccountsParams BuildManageAccountsParams( |
181 const std::string& header_value) { | 207 const std::string& header_value) { |
182 signin::ManageAccountsParams params; | 208 signin::ManageAccountsParams params; |
183 MirrorResponseHeaderDictionary header_dictionary = | 209 MirrorResponseHeaderDictionary header_dictionary = |
184 ParseMirrorResponseHeader(header_value); | 210 ParseMirrorResponseHeader(header_value); |
185 MirrorResponseHeaderDictionary::const_iterator it = header_dictionary.begin(); | 211 MirrorResponseHeaderDictionary::const_iterator it = header_dictionary.begin(); |
186 for (; it != header_dictionary.end(); ++it) { | 212 for (; it != header_dictionary.end(); ++it) { |
187 const std::string key_name(it->first); | 213 const std::string key_name(it->first); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 url, google_util::ALLOW_SUBDOMAIN, | 270 url, google_util::ALLOW_SUBDOMAIN, |
245 google_util::DISALLOW_NON_STANDARD_PORTS) || | 271 google_util::DISALLOW_NON_STANDARD_PORTS) || |
246 google_util::IsYoutubeDomainUrl( | 272 google_util::IsYoutubeDomainUrl( |
247 url, google_util::ALLOW_SUBDOMAIN, | 273 url, google_util::ALLOW_SUBDOMAIN, |
248 google_util::DISALLOW_NON_STANDARD_PORTS)); | 274 google_util::DISALLOW_NON_STANDARD_PORTS)); |
249 return is_google_url || IsDriveOrigin(origin) || | 275 return is_google_url || IsDriveOrigin(origin) || |
250 gaia::IsGaiaSignonRealm(origin); | 276 gaia::IsGaiaSignonRealm(origin); |
251 } | 277 } |
252 | 278 |
253 } // namespace signin | 279 } // namespace signin |
OLD | NEW |