setup_flow_login_step.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1// Copyright (c) 2011 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/remoting/setup_flow_login_step.h"
6
7#include "base/json/json_reader.h"
8#include "base/json/json_writer.h"
9#include "base/string_util.h"
10#include "base/utf_string_conversions.h"
11#include "base/values.h"
12#include "chrome/browser/dom_ui/dom_ui_util.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/browser/remoting/setup_flow_get_status_step.h"
15#include "chrome/common/net/gaia/gaia_constants.h"
16#include "chrome/common/net/gaia/google_service_auth_error.h"
17
18namespace remoting {
19
20static const wchar_t kLoginIFrameXPath[] = L"//iframe[@id='login']";
21
22SetupFlowLoginStep::SetupFlowLoginStep() { }
23SetupFlowLoginStep::~SetupFlowLoginStep() { }
24
25void SetupFlowLoginStep::HandleMessage(const std::string& message,
26                                       const Value* arg) {
27  if (message == "SubmitAuth") {
28    DCHECK(arg);
29
30    std::string json;
31    if (!arg->GetAsString(&json) || json.empty()) {
32      NOTREACHED();
33      return;
34    }
35
36    scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
37    if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) {
38      NOTREACHED() << "Unable to parse auth data";
39      return;
40    }
41
42    CHECK(parsed_value->IsType(Value::TYPE_DICTIONARY));
43
44    std::string username, password, captcha;
45    const DictionaryValue* result =
46        static_cast<const DictionaryValue*>(parsed_value.get());
47    if (!result->GetString("user", &username) ||
48        !result->GetString("pass", &password) ||
49        !result->GetString("captcha", &captcha)) {
50      NOTREACHED() << "Unable to parse auth data";
51      return;
52    }
53
54    OnUserSubmittedAuth(username, password, captcha);
55  }
56}
57
58void SetupFlowLoginStep::Cancel() {
59  if (authenticator_.get())
60    authenticator_->CancelRequest();
61}
62
63void SetupFlowLoginStep::OnUserSubmittedAuth(const std::string& user,
64                                             const std::string& password,
65                                             const std::string& captcha) {
66  flow()->context()->login = user;
67
68  // Start the authenticator.
69  authenticator_.reset(
70      new GaiaAuthFetcher(this, GaiaConstants::kChromeSource,
71                          flow()->profile()->GetRequestContext()));
72  authenticator_->StartClientLogin(user, password,
73                                   GaiaConstants::kRemotingService,
74                                   "", captcha,
75                                   GaiaAuthFetcher::HostedAccountsAllowed);
76}
77
78void SetupFlowLoginStep::OnClientLoginSuccess(
79    const GaiaAuthConsumer::ClientLoginResult& credentials) {
80  // Save the token for remoting.
81  flow()->context()->remoting_token = credentials.token;
82
83  // After login has succeeded try to fetch the token for sync.
84  // We need the token for sync to connect to the talk network.
85  authenticator_->StartIssueAuthToken(credentials.sid, credentials.lsid,
86                                      GaiaConstants::kSyncService);
87}
88
89void SetupFlowLoginStep::OnClientLoginFailure(
90    const GoogleServiceAuthError& error) {
91  ShowGaiaFailed(error);
92  authenticator_.reset();
93}
94
95void SetupFlowLoginStep::OnIssueAuthTokenSuccess(
96    const std::string& service, const std::string& auth_token) {
97  // Save the sync token.
98  flow()->context()->talk_token = auth_token;
99  authenticator_.reset();
100
101  FinishStep(new SetupFlowGetStatusStep());
102}
103
104void SetupFlowLoginStep::OnIssueAuthTokenFailure(const std::string& service,
105    const GoogleServiceAuthError& error) {
106  ShowGaiaFailed(error);
107  authenticator_.reset();
108}
109
110void SetupFlowLoginStep::DoStart() {
111  DictionaryValue args;
112  // TODO(sergeyu): Supply current login name if the service was started before.
113  args.SetString("user", "");
114  args.SetBoolean("editable_user", true);
115  ShowGaiaLogin(args);
116}
117
118void SetupFlowLoginStep::ShowGaiaLogin(const DictionaryValue& args) {
119  DOMUI* dom_ui = flow()->dom_ui();
120  DCHECK(dom_ui);
121
122  dom_ui->CallJavascriptFunction(L"showLogin");
123
124  std::string json;
125  base::JSONWriter::Write(&args, false, &json);
126  std::wstring javascript = std::wstring(L"showGaiaLogin") +
127      L"(" + UTF8ToWide(json) + L");";
128  ExecuteJavascriptInIFrame(kLoginIFrameXPath, javascript);
129}
130
131void SetupFlowLoginStep::ShowGaiaFailed(const GoogleServiceAuthError& error) {
132  DictionaryValue args;
133  args.SetString("user", "");
134  args.SetInteger("error", error.state());
135  args.SetBoolean("editable_user", true);
136  args.SetString("captchaUrl", error.captcha().image_url.spec());
137  ShowGaiaLogin(args);
138}
139
140}  // namespace remoting
141