// Copyright (c) 2011 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/remoting/setup_flow_login_step.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/remoting/setup_flow_get_status_step.h" #include "chrome/common/net/gaia/gaia_constants.h" #include "chrome/common/net/gaia/google_service_auth_error.h" namespace remoting { static const wchar_t kLoginIFrameXPath[] = L"//iframe[@id='login']"; SetupFlowLoginStep::SetupFlowLoginStep() { } SetupFlowLoginStep::SetupFlowLoginStep(const string16& error_message) : error_message_(error_message) { } SetupFlowLoginStep::~SetupFlowLoginStep() { } void SetupFlowLoginStep::HandleMessage(const std::string& message, const Value* arg) { if (message == "SubmitAuth") { DCHECK(arg); std::string json; if (!arg->GetAsString(&json) || json.empty()) { NOTREACHED(); return; } scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false)); if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) { NOTREACHED() << "Unable to parse auth data"; return; } CHECK(parsed_value->IsType(Value::TYPE_DICTIONARY)); std::string username, password, captcha, access_code; const DictionaryValue* result = static_cast<const DictionaryValue*>(parsed_value.get()); if (!result->GetString("user", &username) || !result->GetString("pass", &password) || !result->GetString("captcha", &captcha) || !result->GetString("access_code", &access_code)) { NOTREACHED() << "Unable to parse auth data"; return; } OnUserSubmittedAuth(username, password, captcha, access_code); } } void SetupFlowLoginStep::Cancel() { if (authenticator_.get()) authenticator_->CancelRequest(); } void SetupFlowLoginStep::OnUserSubmittedAuth(const std::string& user, const std::string& password, const std::string& captcha, const std::string& access_code) { flow()->context()->login = user; // Start the authenticator. authenticator_.reset( new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, flow()->profile()->GetRequestContext())); std::string remoting_password; if (!access_code.empty()) remoting_password = access_code; else remoting_password = password; authenticator_->StartClientLogin(user, remoting_password, GaiaConstants::kRemotingService, "", captcha, GaiaAuthFetcher::HostedAccountsAllowed); } void SetupFlowLoginStep::OnClientLoginSuccess( const GaiaAuthConsumer::ClientLoginResult& credentials) { // Save the token for remoting. flow()->context()->remoting_token = credentials.token; // After login has succeeded try to fetch the token for sync. // We need the token for sync to connect to the talk network. authenticator_->StartIssueAuthToken(credentials.sid, credentials.lsid, GaiaConstants::kSyncService); } void SetupFlowLoginStep::OnClientLoginFailure( const GoogleServiceAuthError& error) { ShowGaiaFailed(error); authenticator_.reset(); } void SetupFlowLoginStep::OnIssueAuthTokenSuccess( const std::string& service, const std::string& auth_token) { // Save the sync token. flow()->context()->talk_token = auth_token; authenticator_.reset(); FinishStep(new SetupFlowGetStatusStep()); } void SetupFlowLoginStep::OnIssueAuthTokenFailure(const std::string& service, const GoogleServiceAuthError& error) { ShowGaiaFailed(error); authenticator_.reset(); } void SetupFlowLoginStep::DoStart() { DictionaryValue args; // TODO(sergeyu): Supply current login name if the service was started before. args.SetString("user", ""); args.SetBoolean("editable_user", true); if (!error_message_.empty()) args.SetString("error_message", error_message_); ShowGaiaLogin(args); } void SetupFlowLoginStep::ShowGaiaLogin(const DictionaryValue& args) { WebUI* web_ui = flow()->web_ui(); DCHECK(web_ui); web_ui->CallJavascriptFunction("showLogin"); std::string json; base::JSONWriter::Write(&args, false, &json); std::wstring javascript = std::wstring(L"showGaiaLogin(") + UTF8ToWide(json) + L");"; ExecuteJavascriptInIFrame(kLoginIFrameXPath, javascript); } void SetupFlowLoginStep::ShowGaiaFailed(const GoogleServiceAuthError& error) { DictionaryValue args; args.SetInteger("error", error.state()); args.SetBoolean("editable_user", true); args.SetString("captchaUrl", error.captcha().image_url.spec()); ShowGaiaLogin(args); } } // namespace remoting