13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 23f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 33f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// found in the LICENSE file. 43f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 53f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/remoting/setup_flow_login_step.h" 63f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 73f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/json/json_reader.h" 83f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/json/json_writer.h" 93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/string_util.h" 103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/utf_string_conversions.h" 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/values.h" 123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/profiles/profile.h" 133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/remoting/setup_flow_get_status_step.h" 143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/common/net/gaia/gaia_constants.h" 153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/common/net/gaia/google_service_auth_error.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace remoting { 183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstatic const wchar_t kLoginIFrameXPath[] = L"//iframe[@id='login']"; 203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 213f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenSetupFlowLoginStep::SetupFlowLoginStep() { } 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSetupFlowLoginStep::SetupFlowLoginStep(const string16& error_message) 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : error_message_(error_message) { 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 273f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenSetupFlowLoginStep::~SetupFlowLoginStep() { } 283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::HandleMessage(const std::string& message, 303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const Value* arg) { 313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (message == "SubmitAuth") { 323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(arg); 333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::string json; 353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!arg->GetAsString(&json) || json.empty()) { 363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NOTREACHED(); 373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false)); 413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) { 423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NOTREACHED() << "Unable to parse auth data"; 433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CHECK(parsed_value->IsType(Value::TYPE_DICTIONARY)); 473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string username, password, captcha, access_code; 493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const DictionaryValue* result = 503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<const DictionaryValue*>(parsed_value.get()); 513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!result->GetString("user", &username) || 523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen !result->GetString("pass", &password) || 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !result->GetString("captcha", &captcha) || 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !result->GetString("access_code", &access_code)) { 553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NOTREACHED() << "Unable to parse auth data"; 563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen OnUserSubmittedAuth(username, password, captcha, access_code); 603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::Cancel() { 643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (authenticator_.get()) 653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen authenticator_->CancelRequest(); 663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::OnUserSubmittedAuth(const std::string& user, 693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const std::string& password, 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& captcha, 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& access_code) { 723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen flow()->context()->login = user; 733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Start the authenticator. 753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen authenticator_.reset( 763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, 773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen flow()->profile()->GetRequestContext())); 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string remoting_password; 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!access_code.empty()) 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen remoting_password = access_code; 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen else 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen remoting_password = password; 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen authenticator_->StartClientLogin(user, remoting_password, 863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen GaiaConstants::kRemotingService, 873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen "", captcha, 883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen GaiaAuthFetcher::HostedAccountsAllowed); 893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::OnClientLoginSuccess( 923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const GaiaAuthConsumer::ClientLoginResult& credentials) { 933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Save the token for remoting. 943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen flow()->context()->remoting_token = credentials.token; 953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // After login has succeeded try to fetch the token for sync. 973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // We need the token for sync to connect to the talk network. 983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen authenticator_->StartIssueAuthToken(credentials.sid, credentials.lsid, 993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen GaiaConstants::kSyncService); 1003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::OnClientLoginFailure( 1033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const GoogleServiceAuthError& error) { 1043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ShowGaiaFailed(error); 1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen authenticator_.reset(); 1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::OnIssueAuthTokenSuccess( 1093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const std::string& service, const std::string& auth_token) { 1103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Save the sync token. 1113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen flow()->context()->talk_token = auth_token; 1123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen authenticator_.reset(); 1133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen FinishStep(new SetupFlowGetStatusStep()); 1153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::OnIssueAuthTokenFailure(const std::string& service, 1183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const GoogleServiceAuthError& error) { 1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ShowGaiaFailed(error); 1203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen authenticator_.reset(); 1213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::DoStart() { 1243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DictionaryValue args; 1253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // TODO(sergeyu): Supply current login name if the service was started before. 1263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen args.SetString("user", ""); 1273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen args.SetBoolean("editable_user", true); 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!error_message_.empty()) 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen args.SetString("error_message", error_message_); 1303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ShowGaiaLogin(args); 1313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::ShowGaiaLogin(const DictionaryValue& args) { 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen WebUI* web_ui = flow()->web_ui(); 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(web_ui); 1363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui->CallJavascriptFunction("showLogin"); 1383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::string json; 1403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::JSONWriter::Write(&args, false, &json); 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::wstring javascript = std::wstring(L"showGaiaLogin(") + 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UTF8ToWide(json) + L");"; 1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ExecuteJavascriptInIFrame(kLoginIFrameXPath, javascript); 1443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid SetupFlowLoginStep::ShowGaiaFailed(const GoogleServiceAuthError& error) { 1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DictionaryValue args; 1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen args.SetInteger("error", error.state()); 1493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen args.SetBoolean("editable_user", true); 1503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen args.SetString("captchaUrl", error.captcha().image_url.spec()); 1513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ShowGaiaLogin(args); 1523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} // namespace remoting 155