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