blob: 05e5c9826b3f2a6dbc15739c4a659385c2b90012 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/signin/signin_header_helper.h"
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_renderer_state.h"
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
namespace {
const char kChromeConnectedHeader[] = "X-Chrome-Connected";
const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts";
const char kGaiaAuthExtensionID[] = "mfffpogegjflfpflabcdkioaeobkgjik";
// Show profile avatar bubble on UI thread. Must be called on the UI thread.
void ShowAvatarBubbleUIThread(int child_id, int route_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
#if !defined(OS_ANDROID)
content::WebContents* web_contents =
tab_util::GetWebContentsByID(child_id, route_id);
if (!web_contents)
return;
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
if (browser)
browser->window()->ShowAvatarBubbleFromAvatarButton();
// TODO(guohui): need to handle the case when avatar button is not available.
#endif // OS_ANDROID
}
bool IsDriveOrigin(const GURL& url) {
if (!url.SchemeIsSecure())
return false;
const GURL kGoogleDriveURL("https://drive.google.com");
const GURL kGoogleDocsURL("https://docs.google.com");
return url == kGoogleDriveURL || url == kGoogleDocsURL;
}
} // empty namespace
namespace signin {
void AppendMirrorRequestHeaderIfPossible(
net::URLRequest* request,
const GURL& redirect_url,
ProfileIOData* io_data,
int child_id,
int route_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
// Only set the header for Gaia (in the mirror world) and Drive. Gaia needs
// the header to redirect certain user actions to Chrome native UI. Drive
// needs the header to tell if the current user is connected. The drive path
// is a temporary workaround until the more generic chrome.principals API is
// available.
const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url;
GURL origin(url.GetOrigin());
bool enable_inline = CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableInlineSignin);
if (!enable_inline ||
!profiles::IsNewProfileManagementEnabled() ||
io_data->is_incognito() ||
io_data->google_services_username()->GetValue().empty() ||
(!IsDriveOrigin(origin) &&
!gaia::IsGaiaSignonRealm(origin))) {
return;
}
ExtensionRendererState* renderer_state =
ExtensionRendererState::GetInstance();
ExtensionRendererState::WebViewInfo webview_info;
bool is_guest = renderer_state->GetWebViewInfo(
child_id, route_id, &webview_info);
if (is_guest && webview_info.extension_id == kGaiaAuthExtensionID){
return;
}
std::string account_id(io_data->google_services_account_id()->GetValue());
if (account_id.empty())
account_id = "1"; // Dummy value if focus ID not available yet.
request->SetExtraRequestHeaderByName(
kChromeConnectedHeader, account_id, false);
}
void ProcessMirrorResponseHeaderIfExists(
net::URLRequest* request,
ProfileIOData* io_data,
int child_id,
int route_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
if (gaia::IsGaiaSignonRealm(request->url().GetOrigin()) &&
request->response_headers()->HasHeader(kChromeManageAccountsHeader)) {
DCHECK(profiles::IsNewProfileManagementEnabled() &&
!io_data->is_incognito());
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(ShowAvatarBubbleUIThread, child_id, route_id));
}
}
} // namespace signin