| 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 |