| 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 "chrome/browser/signin/chrome_signin_helper.h" | 5 #include "chrome/browser/signin/chrome_signin_helper.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 10 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "chrome/browser/ui/browser_finder.h" | 32 #include "chrome/browser/ui/browser_finder.h" |
| 33 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" | 33 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" |
| 34 #endif // defined(OS_ANDROID) | 34 #endif // defined(OS_ANDROID) |
| 35 | 35 |
| 36 namespace signin { | 36 namespace signin { |
| 37 | 37 |
| 38 namespace { | 38 namespace { |
| 39 | 39 |
| 40 const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts"; | 40 const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts"; |
| 41 | 41 |
| 42 #if !defined(OS_ANDROID) |
| 43 const char kDiceResponseHeader[] = "X-Chrome-ID-Consistency-Response"; |
| 44 #endif |
| 45 |
| 42 // Processes the mirror response header on the UI thread. Currently depending | 46 // Processes the mirror response header on the UI thread. Currently depending |
| 43 // on the value of |header_value|, it either shows the profile avatar menu, or | 47 // on the value of |header_value|, it either shows the profile avatar menu, or |
| 44 // opens an incognito window/tab. | 48 // opens an incognito window/tab. |
| 45 void ProcessMirrorHeaderUIThread(int child_id, | 49 void ProcessMirrorHeaderUIThread(int child_id, |
| 46 int route_id, | 50 int route_id, |
| 47 ManageAccountsParams manage_accounts_params) { | 51 ManageAccountsParams manage_accounts_params) { |
| 48 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 52 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 49 DCHECK_EQ(switches::AccountConsistencyMethod::kMirror, | 53 DCHECK_EQ(switches::AccountConsistencyMethod::kMirror, |
| 50 switches::GetAccountConsistencyMethod()); | 54 switches::GetAccountConsistencyMethod()); |
| 51 | 55 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false)); | 99 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false)); |
| 96 } else { | 100 } else { |
| 97 signin_metrics::LogAccountReconcilorStateOnGaiaResponse( | 101 signin_metrics::LogAccountReconcilorStateOnGaiaResponse( |
| 98 account_reconcilor->GetState()); | 102 account_reconcilor->GetState()); |
| 99 AccountManagementScreenHelper::OpenAccountManagementScreen(profile, | 103 AccountManagementScreenHelper::OpenAccountManagementScreen(profile, |
| 100 service_type); | 104 service_type); |
| 101 } | 105 } |
| 102 #endif // !defined(OS_ANDROID) | 106 #endif // !defined(OS_ANDROID) |
| 103 } | 107 } |
| 104 | 108 |
| 105 } // namespace | 109 // Looks for the X-Chrome-Manage-Accounts response header, and if found, |
| 106 | 110 // tries to show the avatar bubble in the browser identified by the |
| 107 void FixAccountConsistencyRequestHeader(net::URLRequest* request, | 111 // child/route id. Must be called on IO thread. |
| 108 const GURL& redirect_url, | |
| 109 ProfileIOData* io_data, | |
| 110 int child_id, | |
| 111 int route_id) { | |
| 112 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 113 | |
| 114 if (io_data->IsOffTheRecord()) | |
| 115 return; | |
| 116 | |
| 117 #if !defined(OS_ANDROID) | |
| 118 extensions::WebViewRendererState::WebViewInfo webview_info; | |
| 119 bool is_guest = extensions::WebViewRendererState::GetInstance()->GetInfo( | |
| 120 child_id, route_id, &webview_info); | |
| 121 // Do not set the account consistency header on requests from a native signin | |
| 122 // webview, as identified by an empty extension id which means the webview is | |
| 123 // embedded in a webui page, otherwise user may end up with a blank page as | |
| 124 // gaia uses the header to decide whether it returns 204 for certain end | |
| 125 // points. | |
| 126 if (is_guest && webview_info.owner_host.empty()) | |
| 127 return; | |
| 128 #endif // !defined(OS_ANDROID) | |
| 129 | |
| 130 int profile_mode_mask = PROFILE_MODE_DEFAULT; | |
| 131 if (io_data->incognito_availibility()->GetValue() == | |
| 132 IncognitoModePrefs::DISABLED || | |
| 133 IncognitoModePrefs::ArePlatformParentalControlsEnabled()) { | |
| 134 profile_mode_mask |= PROFILE_MODE_INCOGNITO_DISABLED; | |
| 135 } | |
| 136 | |
| 137 // If new url is eligible to have the header, add it, otherwise remove it. | |
| 138 AppendOrRemoveAccountConsistentyRequestHeader( | |
| 139 request, redirect_url, io_data->google_services_account_id()->GetValue(), | |
| 140 io_data->GetCookieSettings(), profile_mode_mask); | |
| 141 } | |
| 142 | |
| 143 void ProcessMirrorResponseHeaderIfExists(net::URLRequest* request, | 112 void ProcessMirrorResponseHeaderIfExists(net::URLRequest* request, |
| 144 ProfileIOData* io_data, | 113 ProfileIOData* io_data, |
| 145 int child_id, | 114 int child_id, |
| 146 int route_id) { | 115 int route_id) { |
| 147 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 116 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 148 | 117 |
| 149 const content::ResourceRequestInfo* info = | 118 const content::ResourceRequestInfo* info = |
| 150 content::ResourceRequestInfo::ForRequest(request); | 119 content::ResourceRequestInfo::ForRequest(request); |
| 151 if (!(info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME)) | 120 if (!(info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME)) |
| 152 return; | 121 return; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 183 if (params.service_type == GAIA_SERVICE_TYPE_NONE) | 152 if (params.service_type == GAIA_SERVICE_TYPE_NONE) |
| 184 return; | 153 return; |
| 185 | 154 |
| 186 params.child_id = child_id; | 155 params.child_id = child_id; |
| 187 params.route_id = route_id; | 156 params.route_id = route_id; |
| 188 content::BrowserThread::PostTask( | 157 content::BrowserThread::PostTask( |
| 189 content::BrowserThread::UI, FROM_HERE, | 158 content::BrowserThread::UI, FROM_HERE, |
| 190 base::Bind(ProcessMirrorHeaderUIThread, child_id, route_id, params)); | 159 base::Bind(ProcessMirrorHeaderUIThread, child_id, route_id, params)); |
| 191 } | 160 } |
| 192 | 161 |
| 162 #if !defined(OS_ANDROID) |
| 163 void ProcessDiceResponseHeaderIfExists(net::URLRequest* request, |
| 164 ProfileIOData* io_data) { |
| 165 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 166 |
| 167 if (io_data->IsOffTheRecord()) |
| 168 return; |
| 169 |
| 170 const content::ResourceRequestInfo* info = |
| 171 content::ResourceRequestInfo::ForRequest(request); |
| 172 if (!(info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME)) |
| 173 return; |
| 174 |
| 175 if (!gaia::IsGaiaSignonRealm(request->url().GetOrigin())) |
| 176 return; |
| 177 |
| 178 if (switches::GetAccountConsistencyMethod() != |
| 179 switches::AccountConsistencyMethod::kDice) { |
| 180 return; |
| 181 } |
| 182 |
| 183 net::HttpResponseHeaders* response_headers = request->response_headers(); |
| 184 if (!response_headers) |
| 185 return; |
| 186 |
| 187 std::string header_value; |
| 188 if (!response_headers->GetNormalizedHeader(kDiceResponseHeader, |
| 189 &header_value)) { |
| 190 return; |
| 191 } |
| 192 |
| 193 DiceResponseParams params = BuildDiceResponseParams(header_value); |
| 194 // If the request does not have a response header or if the header contains |
| 195 // garbage, then |user_intention| is set to |NONE|. |
| 196 if (params.user_intention == DiceAction::NONE) |
| 197 return; |
| 198 |
| 199 // TODO(droger): Process the Dice header: on sign-in, exchange the |
| 200 // authorization code for a refresh token, on sign-out just follow the |
| 201 // sign-out URL. |
| 202 } |
| 203 #endif // !defined(OS_ANDROID) |
| 204 |
| 205 } // namespace |
| 206 |
| 207 void FixAccountConsistencyRequestHeader(net::URLRequest* request, |
| 208 const GURL& redirect_url, |
| 209 ProfileIOData* io_data, |
| 210 int child_id, |
| 211 int route_id) { |
| 212 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 213 |
| 214 if (io_data->IsOffTheRecord()) |
| 215 return; |
| 216 |
| 217 #if !defined(OS_ANDROID) |
| 218 extensions::WebViewRendererState::WebViewInfo webview_info; |
| 219 bool is_guest = extensions::WebViewRendererState::GetInstance()->GetInfo( |
| 220 child_id, route_id, &webview_info); |
| 221 // Do not set the account consistency header on requests from a native signin |
| 222 // webview, as identified by an empty extension id which means the webview is |
| 223 // embedded in a webui page, otherwise user may end up with a blank page as |
| 224 // gaia uses the header to decide whether it returns 204 for certain end |
| 225 // points. |
| 226 if (is_guest && webview_info.owner_host.empty()) |
| 227 return; |
| 228 #endif // !defined(OS_ANDROID) |
| 229 |
| 230 int profile_mode_mask = PROFILE_MODE_DEFAULT; |
| 231 if (io_data->incognito_availibility()->GetValue() == |
| 232 IncognitoModePrefs::DISABLED || |
| 233 IncognitoModePrefs::ArePlatformParentalControlsEnabled()) { |
| 234 profile_mode_mask |= PROFILE_MODE_INCOGNITO_DISABLED; |
| 235 } |
| 236 |
| 237 // If new url is eligible to have the header, add it, otherwise remove it. |
| 238 AppendOrRemoveAccountConsistentyRequestHeader( |
| 239 request, redirect_url, io_data->google_services_account_id()->GetValue(), |
| 240 io_data->GetCookieSettings(), profile_mode_mask); |
| 241 } |
| 242 |
| 243 void ProcessAccountConsistencyResponseHeaders(net::URLRequest* request, |
| 244 const GURL& redirect_url, |
| 245 ProfileIOData* io_data, |
| 246 int child_id, |
| 247 int route_id) { |
| 248 if (redirect_url.is_empty()) { |
| 249 // This is not a redirect. |
| 250 |
| 251 // See if the response contains the X-Chrome-Manage-Accounts header. If so |
| 252 // show the profile avatar bubble so that user can complete signin/out |
| 253 // action the native UI. |
| 254 signin::ProcessMirrorResponseHeaderIfExists(request, io_data, child_id, |
| 255 route_id); |
| 256 } else { |
| 257 // This is a redirect. |
| 258 |
| 259 #if !defined(OS_ANDROID) |
| 260 // Process the Dice header: on sign-in, exchange the authorization code for |
| 261 // a refresh token, on sign-out just follow the sign-out URL. |
| 262 signin::ProcessDiceResponseHeaderIfExists(request, io_data); |
| 263 #endif |
| 264 } |
| 265 } |
| 266 |
| 193 } // namespace signin | 267 } // namespace signin |
| OLD | NEW |