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