added activate page in wizard #4168

This commit is contained in:
XinyuHou 2015-02-05 14:17:34 +00:00
parent 097f4c4c1f
commit aa46fe91a7
15 changed files with 481 additions and 6 deletions

View File

@ -50,7 +50,8 @@ SOURCES += src/main.cpp \
src/ZeroconfService.cpp \ src/ZeroconfService.cpp \
src/DataDownloader.cpp \ src/DataDownloader.cpp \
src/AddClientDialog.cpp \ src/AddClientDialog.cpp \
src/CommandProcess.cpp src/CommandProcess.cpp \
src/WebClient.cpp
HEADERS += src/MainWindow.h \ HEADERS += src/MainWindow.h \
src/AboutDialog.h \ src/AboutDialog.h \
src/ServerConfig.h \ src/ServerConfig.h \
@ -86,7 +87,9 @@ HEADERS += src/MainWindow.h \
src/ZeroconfService.h \ src/ZeroconfService.h \
src/DataDownloader.h \ src/DataDownloader.h \
src/AddClientDialog.h \ src/AddClientDialog.h \
src/CommandProcess.h src/CommandProcess.h \
src/WebClient.h \
src/EditionType.h
RESOURCES += res/Synergy.qrc RESOURCES += res/Synergy.qrc
RC_FILE = res/win/Synergy.rc RC_FILE = res/win/Synergy.rc
macx { macx {

View File

@ -120,6 +120,137 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWizardPage" name="m_pActivatePage">
<property name="title">
<string>Activate</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="m_pRadioButtonActivate">
<property name="text">
<string>I have purchased and would like to activate...</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="horizontalSpacing">
<number>20</number>
</property>
<property name="verticalSpacing">
<number>10</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="m_pLabelEmail">
<property name="text">
<string>Email:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_pLineEditEmail">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Passward:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="m_pLineEditPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;a href=&quot;https://synergy-project.org/account/reset/&quot;&gt;Forget password&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="m_pRadioButtonSkip">
<property name="text">
<string>I would like to skip activation</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>500</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="m_pNodePage"> <widget class="QWizardPage" name="m_pNodePage">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">

View File

@ -17,6 +17,7 @@
*/ */
#include "AppConfig.h" #include "AppConfig.h"
#include "EditionType.h"
#include "QUtility.h" #include "QUtility.h"
#include <QtCore> #include <QtCore>
@ -127,6 +128,9 @@ void AppConfig::loadSettings()
m_AutoConfig = settings().value("autoConfig", true).toBool(); m_AutoConfig = settings().value("autoConfig", true).toBool();
m_ElevateMode = settings().value("elevateMode", false).toBool(); m_ElevateMode = settings().value("elevateMode", false).toBool();
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool(); m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
m_Edition = settings().value("edition", Unknown).toInt();
m_ActivateEmail = settings().value("activateEmail", "").toString();
m_UserToken = settings().value("userToken", "").toString();
} }
void AppConfig::saveSettings() void AppConfig::saveSettings()
@ -145,6 +149,9 @@ void AppConfig::saveSettings()
settings().setValue("autoConfig", m_AutoConfig); settings().setValue("autoConfig", m_AutoConfig);
settings().setValue("elevateMode", m_ElevateMode); settings().setValue("elevateMode", m_ElevateMode);
settings().setValue("autoConfigPrompted", m_AutoConfigPrompted); settings().setValue("autoConfigPrompted", m_AutoConfigPrompted);
settings().setValue("edition", m_Edition);
settings().setValue("activateEmail", m_ActivateEmail);
settings().setValue("userToken", m_UserToken);
} }
void AppConfig::setCryptoPass(const QString &s) void AppConfig::setCryptoPass(const QString &s)

View File

@ -32,7 +32,7 @@
// 2: added language page // 2: added language page
// 3: added premium page and removed // 3: added premium page and removed
// //
const int kWizardVersion = 3; const int kWizardVersion = 4;
class QSettings; class QSettings;
class SettingsDialog; class SettingsDialog;
@ -72,6 +72,12 @@ class AppConfig
void setAutoConfig(bool autoConfig); void setAutoConfig(bool autoConfig);
bool autoConfigPrompted() { return m_AutoConfigPrompted; } bool autoConfigPrompted() { return m_AutoConfigPrompted; }
void setAutoConfigPrompted(bool prompted); void setAutoConfigPrompted(bool prompted);
void setEdition(int e) { m_Edition = e; }
int edition() { return m_Edition; }
void setActivateEmail(QString e) { m_ActivateEmail = e; }
QString activateEmail() { return m_ActivateEmail; }
void setUserToken(QString t) { m_UserToken = t; }
QString userToken() { return m_UserToken; }
QString synergysName() const { return m_SynergysName; } QString synergysName() const { return m_SynergysName; }
QString synergycName() const { return m_SynergycName; } QString synergycName() const { return m_SynergycName; }
@ -118,6 +124,9 @@ class AppConfig
bool m_AutoConfig; bool m_AutoConfig;
bool m_ElevateMode; bool m_ElevateMode;
bool m_AutoConfigPrompted; bool m_AutoConfigPrompted;
int m_Edition;
QString m_ActivateEmail;
QString m_UserToken;
static const char m_SynergysName[]; static const char m_SynergysName[];
static const char m_SynergycName[]; static const char m_SynergycName[];

27
src/gui/src/EditionType.h Normal file
View File

@ -0,0 +1,27 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2015 Synergy Si Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EDITIONTYPE_H
#define EDITIONTYPE_H
enum qEditionType {
Basic,
Pro,
Unknown
};
#endif // EDITIONTYPE_H

View File

@ -28,6 +28,8 @@
#include "ZeroconfService.h" #include "ZeroconfService.h"
#include "DataDownloader.h" #include "DataDownloader.h"
#include "CommandProcess.h" #include "CommandProcess.h"
#include "EditionType.h"
#include "QUtility.h"
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
@ -812,10 +814,21 @@ void MainWindow::changeEvent(QEvent* event)
switch (event->type()) switch (event->type())
{ {
case QEvent::LanguageChange: case QEvent::LanguageChange:
{
retranslateUi(this); retranslateUi(this);
retranslateMenuBar(); retranslateMenuBar();
break;
QString mac = getFirstMacAddress();
QString hashSrc = m_AppConfig.activateEmail() + mac;
QString hashResult = hash(hashSrc);
if (hashResult == m_AppConfig.userToken()) {
setEdition(m_AppConfig.edition());
}
else {
setEdition(Unknown);
}
break;
}
default: default:
QMainWindow::changeEvent(event); QMainWindow::changeEvent(event);
} }
@ -872,6 +885,22 @@ int MainWindow::checkWinArch()
return unknown; return unknown;
} }
void MainWindow::setEdition(int type)
{
QString title;
if (type == Basic) {
title = "Synergy Basic";
}
else if (type == Pro) {
title = "Synergy Pro";
}
else {
title = "Synergy (UNREGISTERED)";
}
setWindowTitle(title);
}
void MainWindow::on_m_pGroupClient_toggled(bool on) void MainWindow::on_m_pGroupClient_toggled(bool on)
{ {
m_pGroupServer->setChecked(!on); m_pGroupServer->setChecked(!on);

View File

@ -112,6 +112,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void updateZeroconfService(); void updateZeroconfService();
void serverDetected(const QString name); void serverDetected(const QString name);
int checkWinArch(); int checkWinArch();
void setEdition(int type);
public slots: public slots:
void appendLogRaw(const QString& text); void appendLogRaw(const QString& text);

View File

@ -17,6 +17,8 @@
#include "SetupWizard.h" #include "SetupWizard.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "WebClient.h"
#include "EditionType.h"
#include "QSynergyApplication.h" #include "QSynergyApplication.h"
#include "QUtility.h" #include "QUtility.h"
@ -24,7 +26,8 @@
SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) : SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
m_MainWindow(mainWindow), m_MainWindow(mainWindow),
m_StartMain(startMain) m_StartMain(startMain),
m_Edition(Unknown)
{ {
setupUi(this); setupUi(this);
@ -51,6 +54,9 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
m_Locale.fillLanguageComboBox(m_pComboLanguage); m_Locale.fillLanguageComboBox(m_pComboLanguage);
setIndexFromItemData(m_pComboLanguage, m_MainWindow.appConfig().language()); setIndexFromItemData(m_pComboLanguage, m_MainWindow.appConfig().language());
AppConfig& appConfig = m_MainWindow.appConfig();
m_pLineEditEmail->setText(appConfig.activateEmail());
} }
@ -64,7 +70,36 @@ bool SetupWizard::validateCurrentPage()
message.setWindowTitle(tr("Setup Synergy")); message.setWindowTitle(tr("Setup Synergy"));
message.setIcon(QMessageBox::Information); message.setIcon(QMessageBox::Information);
if (currentPage() == m_pNodePage) if (currentPage() == m_pActivatePage)
{
if (m_pRadioButtonActivate->isChecked()) {
if (m_pLineEditEmail->text().isEmpty() ||
m_pLineEditPassword->text().isEmpty()) {
message.setText(tr("Please enter your email address and password."));
message.exec();
return false;
}
else {
WebClient webClient;
m_Edition = webClient .getEdition(
m_pLineEditEmail->text(),
m_pLineEditPassword->text(),
message,
this);
if (m_Edition == Unknown) {
return false;
}
else {
return true;
}
}
}
else {
return true;
}
}
else if (currentPage() == m_pNodePage)
{ {
bool result = m_pClientRadioButton->isChecked() || bool result = m_pClientRadioButton->isChecked() ||
m_pServerRadioButton->isChecked(); m_pServerRadioButton->isChecked();
@ -121,6 +156,16 @@ void SetupWizard::accept()
settings.setValue("groupServerChecked", false); settings.setValue("groupServerChecked", false);
} }
if (m_pRadioButtonActivate->isChecked()) {
appConfig.setActivateEmail(m_pLineEditEmail->text());
QString mac = getFirstMacAddress();
QString hashSrc = m_pLineEditEmail->text() + mac;
QString hashResult = hash(hashSrc);
appConfig.setUserToken(hashResult);
appConfig.setEdition(m_Edition);
}
m_MainWindow.setEdition(m_Edition);
settings.sync(); settings.sync();
QWizard::accept(); QWizard::accept();
@ -138,6 +183,7 @@ void SetupWizard::reject()
if (m_StartMain) if (m_StartMain)
{ {
m_MainWindow.setEdition(m_Edition);
m_MainWindow.open(); m_MainWindow.open();
} }
@ -149,3 +195,19 @@ void SetupWizard::on_m_pComboLanguage_currentIndexChanged(int index)
QString ietfCode = m_pComboLanguage->itemData(index).toString(); QString ietfCode = m_pComboLanguage->itemData(index).toString();
QSynergyApplication::getInstance()->switchTranslator(ietfCode); QSynergyApplication::getInstance()->switchTranslator(ietfCode);
} }
void SetupWizard::on_m_pRadioButtonSkip_toggled(bool checked)
{
if (checked) {
m_pLineEditEmail->setEnabled(false);
m_pLineEditPassword->setEnabled(false);
}
}
void SetupWizard::on_m_pRadioButtonActivate_toggled(bool checked)
{
if (checked) {
m_pLineEditEmail->setEnabled(true);
m_pLineEditPassword->setEnabled(true);
}
}

View File

@ -43,7 +43,10 @@ private:
MainWindow& m_MainWindow; MainWindow& m_MainWindow;
bool m_StartMain; bool m_StartMain;
SynergyLocale m_Locale; SynergyLocale m_Locale;
int m_Edition;
private slots: private slots:
void on_m_pRadioButtonActivate_toggled(bool checked);
void on_m_pRadioButtonSkip_toggled(bool checked);
void on_m_pComboLanguage_currentIndexChanged(int index); void on_m_pComboLanguage_currentIndexChanged(int index);
}; };

130
src/gui/src/WebClient.cpp Normal file
View File

@ -0,0 +1,130 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2015 Synergy Si, Std.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WebClient.h"
#include "EditionType.h"
#include "QUtility.h"
#include <QProcess>
#include <QMessageBox>
#include <QCoreApplication>
#include <stdexcept>
int WebClient::getEdition(
const QString& email,
const QString& password,
QMessageBox& message,
QWidget* w)
{
QString responseJson;
int edition = Unknown;
try {
responseJson = request(email, password);
}
catch (std::exception& e)
{
message.critical(
w, "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 edition;
}
QRegExp resultRegex(".*\"result\".*:.*(true|false).*");
if (resultRegex.exactMatch(responseJson)) {
QString boolString = resultRegex.cap(1);
if (boolString == "true") {
QRegExp editionRegex(".*\"edition\".*:.*\"(.+)\",.*");
if (editionRegex.exactMatch(responseJson)) {
QString e = editionRegex.cap(1);
edition = e.toInt();
}
return edition;
}
else if (boolString == "false") {
message.critical(
w, "Error",
tr("Login failed, invalid email or password."));
return edition;
}
}
else {
QRegExp errorRegex(".*\"error\".*:.*\"(.+)\".*");
if (errorRegex.exactMatch(responseJson)) {
// replace "\n" with real new lines.
QString error = errorRegex.cap(1).replace("\\n", "\n");
message.critical(
w, "Error",
tr("Login failed, an error occurred.\n\n%1").arg(error));
return edition;
}
}
message.critical(
w, "Error",
tr("Login failed, an error occurred.\n\nServer response:\n\n%1")
.arg(responseJson));
return edition;
}
QString WebClient::request(const QString& email, const QString& password)
{
QString program(QCoreApplication::applicationDirPath() + "/syntool");
QStringList args("--login-auth");
QProcess process;
process.setReadChannel(QProcess::StandardOutput);
process.start(program, args);
bool success = 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()) {
out = process.readAllStandardOutput();
error = process.readAllStandardError();
}
}
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;
}

41
src/gui/src/WebClient.h Normal file
View File

@ -0,0 +1,41 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2015 Synergy Si, Std.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WEBCLIENT_H
#define WEBCLIENT_H
#include <QString>
#include <QObject>
class QMessageBox;
class QWidget;
class WebClient : public QObject
{
Q_OBJECT
public:
int getEdition(const QString& email,
const QString& password,
QMessageBox& message,
QWidget* w);
private:
QString request(const QString& email, const QString& password);
};
#endif // WEBCLIENT_H

View File

@ -165,6 +165,10 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
args.m_printActiveDesktopName = true; args.m_printActiveDesktopName = true;
return true; return true;
} }
else if (isArg(i, argc, argv, NULL, "--login-auth", 0)) {
args.m_loginAuthenticate = true;
return true;
}
else { else {
return false; return false;
} }

View File

@ -29,6 +29,8 @@
#include "platform/MSWindowsSession.h" #include "platform/MSWindowsSession.h"
#endif #endif
#define PREMIUM_AUTH_URL "https://synergy-project.org/premium/json/auth/"
enum { enum {
kErrorOk, kErrorOk,
kErrorArgs, kErrorArgs,
@ -65,6 +67,9 @@ ToolApp::run(int argc, char** argv)
} }
#endif #endif
} }
else if (m_args.m_loginAuthenticate) {
loginAuth();
}
else { else {
throw XSynergy("Nothing to do"); throw XSynergy("Nothing to do");
} }
@ -85,3 +90,21 @@ void
ToolApp::help() ToolApp::help()
{ {
} }
void
ToolApp::loginAuth()
{
String credentials;
std::cin >> credentials;
size_t separator = credentials.find(':');
String email = credentials.substr(0, separator);
String 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;
}

View File

@ -26,6 +26,10 @@ class ToolApp : public MinimalApp
public: public:
UInt32 run(int argc, char** argv); UInt32 run(int argc, char** argv);
void help(); void help();
private:
void loginAuth();
private: private:
ToolArgs m_args; ToolArgs m_args;
}; };

View File

@ -25,4 +25,5 @@ public:
public: public:
bool m_printActiveDesktopName; bool m_printActiveDesktopName;
bool m_loginAuthenticate;
}; };