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
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/webui/signin/inline_login_handler.h"
6
7#include "base/bind.h"
8#include "base/prefs/pref_service.h"
9#include "base/strings/utf_string_conversions.h"
10#include "base/values.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/profiles/profile.h"
13#include "chrome/browser/signin/signin_promo.h"
14#include "chrome/browser/ui/browser_navigator.h"
15#include "chrome/common/pref_names.h"
16#include "content/public/browser/web_contents.h"
17#include "content/public/browser/web_ui.h"
18#include "google_apis/gaia/gaia_urls.h"
19#include "net/base/url_util.h"
20
21InlineLoginHandler::InlineLoginHandler() {}
22
23InlineLoginHandler::~InlineLoginHandler() {}
24
25void InlineLoginHandler::RegisterMessages() {
26  web_ui()->RegisterMessageCallback("initialize",
27      base::Bind(&InlineLoginHandler::HandleInitializeMessage,
28                  base::Unretained(this)));
29  web_ui()->RegisterMessageCallback("completeLogin",
30      base::Bind(&InlineLoginHandler::HandleCompleteLoginMessage,
31                  base::Unretained(this)));
32  web_ui()->RegisterMessageCallback(
33      "switchToFullTab",
34      base::Bind(&InlineLoginHandler::HandleSwitchToFullTabMessage,
35                 base::Unretained(this)));
36}
37
38void InlineLoginHandler::HandleInitializeMessage(const base::ListValue* args) {
39  base::DictionaryValue params;
40
41  const std::string& app_locale = g_browser_process->GetApplicationLocale();
42  params.SetString("hl", app_locale);
43  GaiaUrls* gaiaUrls = GaiaUrls::GetInstance();
44  params.SetString("gaiaUrl", gaiaUrls->gaia_url().spec());
45  params.SetInteger("authMode", InlineLoginHandler::kDesktopAuthMode);
46
47  const GURL& current_url = web_ui()->GetWebContents()->GetURL();
48  signin::Source source = signin::GetSourceForPromoURL(current_url);
49  if (source == signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT ||
50      source == signin::SOURCE_AVATAR_BUBBLE_SIGN_IN ||
51      source == signin::SOURCE_REAUTH) {
52    // Drop the leading slash in the path.
53    params.SetString(
54        "gaiaPath",
55        GaiaUrls::GetInstance()->embedded_signin_url().path().substr(1));
56  }
57
58  params.SetString(
59      "continueUrl",
60      signin::GetLandingURL(signin::kSignInPromoQueryKeySource,
61                            static_cast<int>(source)).spec());
62
63  std::string default_email;
64  if (source != signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT &&
65      source != signin::SOURCE_REAUTH) {
66    default_email = Profile::FromWebUI(web_ui())->GetPrefs()->GetString(
67        prefs::kGoogleServicesLastUsername);
68  } else {
69    if (!net::GetValueForKeyInQuery(current_url, "email", &default_email))
70      default_email.clear();
71  }
72  if (!default_email.empty())
73    params.SetString("email", default_email);
74
75  std::string frame_url;
76  net::GetValueForKeyInQuery(current_url, "frameUrl", &frame_url);
77  if (!frame_url.empty())
78    params.SetString("frameUrl", frame_url);
79
80  std::string is_constrained;
81  net::GetValueForKeyInQuery(
82      current_url, signin::kSignInPromoQueryKeyConstrained, &is_constrained);
83  if (!is_constrained.empty())
84    params.SetString(signin::kSignInPromoQueryKeyConstrained, is_constrained);
85
86  // TODO(rogerta): this needs to be passed on to gaia somehow.
87  std::string read_only_email;
88  net::GetValueForKeyInQuery(current_url, "readOnlyEmail", &read_only_email);
89  if (!read_only_email.empty())
90    params.SetString("readOnlyEmail", read_only_email);
91
92  SetExtraInitParams(params);
93
94  web_ui()->CallJavascriptFunction("inline.login.loadAuthExtension", params);
95}
96
97void InlineLoginHandler::HandleCompleteLoginMessage(
98    const base::ListValue* args) {
99  CompleteLogin(args);
100}
101
102void InlineLoginHandler::HandleSwitchToFullTabMessage(
103    const base::ListValue* args) {
104  base::string16 url_str;
105  CHECK(args->GetString(0, &url_str));
106
107  content::WebContents* web_contents = web_ui()->GetWebContents();
108  GURL main_frame_url(web_contents->GetURL());
109  main_frame_url = net::AppendOrReplaceQueryParameter(
110      main_frame_url, "frameUrl", base::UTF16ToASCII(url_str));
111
112  // Adds extra parameters to the signin URL so that Chrome will close the tab
113  // and show the account management view of the avatar menu upon completion.
114  main_frame_url = net::AppendOrReplaceQueryParameter(
115      main_frame_url, signin::kSignInPromoQueryKeyAutoClose, "1");
116  main_frame_url = net::AppendOrReplaceQueryParameter(
117      main_frame_url, signin::kSignInPromoQueryKeyShowAccountManagement, "1");
118
119  chrome::NavigateParams params(
120      Profile::FromWebUI(web_ui()),
121      net::AppendOrReplaceQueryParameter(
122          main_frame_url, signin::kSignInPromoQueryKeyConstrained, "0"),
123      ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
124  chrome::Navigate(&params);
125
126  web_ui()->CallJavascriptFunction("inline.login.closeDialog");
127}
128