From f9fe1130ac976abe95cd93adf5ac0d4e54c97300 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Thu, 20 Mar 2014 10:33:33 +0000 Subject: [PATCH] Task #3964 - Make premium login error more verbose --- src/gui/src/PremiumAuth.cpp | 25 ++++++++++++-- src/gui/src/SetupWizard.cpp | 36 ++++++++++++------- src/lib/synergy/ToolApp.cpp | 69 ++++++++++++++++++++++++------------- src/lib/synergy/ToolApp.h | 7 +++- 4 files changed, 98 insertions(+), 39 deletions(-) diff --git a/src/gui/src/PremiumAuth.cpp b/src/gui/src/PremiumAuth.cpp index c14db1ea..624684a0 100644 --- a/src/gui/src/PremiumAuth.cpp +++ b/src/gui/src/PremiumAuth.cpp @@ -20,6 +20,7 @@ #include #include +#include // we use syntool to authenticate because Qt's http library is very // unreliable, and since we're writing platform specific code, use the @@ -32,17 +33,35 @@ QString PremiumAuth::request(const QString& email, const QString& password) QProcess process; process.setReadChannel(QProcess::StandardOutput); process.start(program, args); + bool success = process.waitForStarted(); - if (process.waitForStarted()) + QString out, error; + if (success) { // hash password in case it contains interesting chars. QString credentials(email + ":" + hash(password) + "\n"); process.write(credentials.toStdString().c_str()); if (process.waitForFinished()) { - return process.readAll(); + out = process.readAllStandardOutput(); + error = process.readAllStandardError(); } } - return ""; + out = out.trimmed(); + error = error.trimmed(); + + if (out.isEmpty() || + !error.isEmpty() || + !success || + process.exitCode() != 0) + { + throw std::runtime_error( + QString("Code: %1\nError: %2") + .arg(process.exitCode()) + .arg(error.isEmpty() ? "Unknown" : error) + .toStdString()); + } + + return out; } diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp index 4c1ea594..56cbabc0 100644 --- a/src/gui/src/SetupWizard.cpp +++ b/src/gui/src/SetupWizard.cpp @@ -252,12 +252,20 @@ bool SetupWizard::isPremiumLoginValid(QMessageBox& message) QString email = m_pLineEditPremiumEmail->text(); QString password = m_pLineEditPremiumPassword->text(); - PremiumAuth auth; - QString responseJson = auth.request(email, password); - - if (responseJson.trimmed() == "") { - message.setText(tr("Login failed, could not communicate with server.")); - message.exec(); + QString responseJson; + try + { + PremiumAuth auth; + responseJson = auth.request(email, password); + } + catch (std::exception& e) + { + message.critical( + this, "Error", + tr("Sorry, an error occured while trying to sign in. " + "Please contact the help desk, and provide the " + "following details.\n\n%1") + .arg(e.what())); return false; } @@ -268,8 +276,9 @@ bool SetupWizard::isPremiumLoginValid(QMessageBox& message) return true; } else if (boolString == "false") { - message.setText(tr("Login failed, invalid email or password.")); - message.exec(); + message.critical( + this, "Error", + tr("Login failed, invalid email or password.")); return false; } } @@ -280,13 +289,16 @@ bool SetupWizard::isPremiumLoginValid(QMessageBox& message) // replace "\n" with real new lines. QString error = errorRegex.cap(1).replace("\\n", "\n"); - message.setText(tr("Login failed, an error occurred.\n\n%1").arg(error)); - message.exec(); + message.critical( + this, "Error", + tr("Login failed, an error occurred.\n\n%1").arg(error)); return false; } } - message.setText(tr("Login failed, an error occurred.\n\nServer response:\n\n%1").arg(responseJson)); - message.exec(); + message.critical( + this, "Error", + tr("Login failed, an error occurred.\n\nServer response:\n\n%1") + .arg(responseJson)); return false; } diff --git a/src/lib/synergy/ToolApp.cpp b/src/lib/synergy/ToolApp.cpp index c2935487..d465d5bf 100644 --- a/src/lib/synergy/ToolApp.cpp +++ b/src/lib/synergy/ToolApp.cpp @@ -25,36 +25,59 @@ //#define PREMIUM_AUTH_URL "http://localhost/synergy/premium/json/auth/" #define PREMIUM_AUTH_URL "https://synergy-foss.org/premium/json/auth/" -int +enum { + kErrorOk, + kErrorArgs, + kErrorException, + kErrorUnknown +}; + +UInt32 CToolApp::run(int argc, char** argv) { if (argc <= 1) { std::cerr << "no args" << std::endl; - return 1; + return kErrorArgs; } - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--premium-auth") == 0) { - CString credentials; - std::cin >> credentials; - - size_t separator = credentials.find(':'); - CString email = credentials.substr(0, separator); - CString password = credentials.substr(separator + 1, credentials.length()); - - std::stringstream ss; - ss << PREMIUM_AUTH_URL; - ss << "?email=" << ARCH->internet().urlEncode(email); - ss << "&password=" << password; - - std::cout << ARCH->internet().get(ss.str()) << std::endl; - return 0; - } - else { - std::cerr << "unknown arg: " << argv[i] << std::endl; - return 1; + try { + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--premium-auth") == 0) { + premiumAuth(); + return kErrorOk; + } + else { + std::cerr << "unknown arg: " << argv[i] << std::endl; + return kErrorArgs; + } } } + catch (std::exception& e) { + std::cerr << e.what() << std::endl; + return kErrorException; + } + catch (...) { + std::cerr << "unknown error" << std::endl; + return kErrorUnknown; + } - return 0; + return kErrorOk; +} + +void +CToolApp::premiumAuth() +{ + CString credentials; + std::cin >> credentials; + + size_t separator = credentials.find(':'); + CString email = credentials.substr(0, separator); + CString password = credentials.substr(separator + 1, credentials.length()); + + std::stringstream ss; + ss << PREMIUM_AUTH_URL; + ss << "?email=" << ARCH->internet().urlEncode(email); + ss << "&password=" << password; + + std::cout << ARCH->internet().get(ss.str()) << std::endl; } diff --git a/src/lib/synergy/ToolApp.h b/src/lib/synergy/ToolApp.h index b1ad4cb9..a28b74f7 100644 --- a/src/lib/synergy/ToolApp.h +++ b/src/lib/synergy/ToolApp.h @@ -17,7 +17,12 @@ #pragma once +#include "common/basic_types.h" + class CToolApp { public: - int run(int argc, char** argv); + UInt32 run(int argc, char** argv); + +private: + void premiumAuth(); };