added premium login page.

This commit is contained in:
Nick Bolton 2013-06-04 17:37:27 +00:00
parent 9f25a1efcd
commit c9f0360081
8 changed files with 460 additions and 26 deletions

View File

@ -10,6 +10,12 @@
<height>390</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>500</width>
@ -114,6 +120,224 @@
</item>
</layout>
</widget>
<widget class="QWizardPage" name="m_pPremiumUserPage">
<property name="title">
<string>Synergy Premium</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Synergy Premium users have access to extra features. The latest feature is encryption, which keeps sensitive information (e.g. passwords) safer when typed. These features are funded by Synergy Premium users. You can create an account for as little as $1.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8">
<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_pRadioButtonPremiumLogin">
<property name="text">
<string>Yes, I have an account</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_5">
<item row="1" column="1">
<widget class="QLineEdit" name="m_pLineEditPremiumPassword">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="m_pLabel_29">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>&amp;Password:</string>
</property>
<property name="indent">
<number>10</number>
</property>
<property name="buddy">
<cstring>m_pLineEditPremiumPassword</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="m_pLabel_28">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>&amp;Email:</string>
</property>
<property name="indent">
<number>10</number>
</property>
<property name="buddy">
<cstring>m_pLineEditPremiumEmail</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_pLineEditPremiumEmail">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="m_pLabelForgotPassword">
<property name="text">
<string>&lt;a href=&quot;https://synergy-foss.org/premium/reset/&quot;&gt;Forgot password&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QRadioButton" name="m_pRadioButtonPremiumRegister">
<property name="text">
<string>I want to sign up now</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_pRadioButtonPremiumLater">
<property name="text">
<string>Maybe later</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_9">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="m_pNodePage">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -234,7 +458,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Network traffic can be easily monitored. Using encryption can reduce the risk that sensitive information will be revealed to others (for example, passwords).</string>
<string>Only available to Synergy Premium users.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -252,7 +476,33 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Network traffic can be easily monitored. Using encryption can reduce the risk that sensitive information will be revealed to others (for example, passwords).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_10">
<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>
@ -418,12 +668,12 @@
<number>10</number>
</property>
<property name="buddy">
<cstring>m_pLineEditCryptoPass</cstring>
<cstring>m_pLineEditCryptoPassword1</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="m_pLineEditCryptoPass">
<widget class="QLineEdit" name="m_pLineEditCryptoPassword1">
<property name="enabled">
<bool>true</bool>
</property>
@ -477,12 +727,12 @@
<number>10</number>
</property>
<property name="buddy">
<cstring>m_pLineEditCryptoPassConfirm</cstring>
<cstring>m_pLineEditCryptoPassword2</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="m_pLineEditCryptoPassConfirm">
<widget class="QLineEdit" name="m_pLineEditCryptoPassword2">
<property name="enabled">
<bool>true</bool>
</property>
@ -521,6 +771,19 @@
</layout>
</widget>
</widget>
<tabstops>
<tabstop>m_pComboLanguage</tabstop>
<tabstop>m_pRadioButtonPremiumLogin</tabstop>
<tabstop>m_pLineEditPremiumEmail</tabstop>
<tabstop>m_pLineEditPremiumPassword</tabstop>
<tabstop>m_pRadioButtonPremiumRegister</tabstop>
<tabstop>m_pRadioButtonPremiumLater</tabstop>
<tabstop>m_pServerRadioButton</tabstop>
<tabstop>m_pClientRadioButton</tabstop>
<tabstop>m_pComboCryptoMode</tabstop>
<tabstop>m_pLineEditCryptoPassword1</tabstop>
<tabstop>m_pLineEditCryptoPassword2</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -17,6 +17,7 @@
*/
#include "AppConfig.h"
#include "QUtility.h"
#include <QtCore>
#include <QtNetwork>
@ -161,6 +162,8 @@ void AppConfig::loadSettings()
m_CryptoPass = settings().value("cryptoPass", "").toString();
m_CryptoMode = (CryptoMode)settings().value("cryptoMode", Disabled).toInt();
m_Language = settings().value("language", QLocale::system().name()).toString();
m_PremiumEmail= settings().value("premiumEmail", "").toString();
m_PremiumToken = settings().value("premiumToken", "").toString();
}
void AppConfig::saveSettings()
@ -180,13 +183,8 @@ void AppConfig::saveSettings()
settings().setValue("cryptoPass", m_CryptoPass);
settings().setValue("cryptoMode", m_CryptoMode);
settings().setValue("language", m_Language);
}
QString AppConfig::hash(const QString& string)
{
QByteArray data = string.toUtf8();
QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
return hash.toHex();
settings().setValue("premiumEmail", m_PremiumEmail);
settings().setValue("premiumToken", m_PremiumToken);
}
void AppConfig::setCryptoPass(const QString &s)
@ -226,3 +224,10 @@ QString AppConfig::cryptoModeString() const
return "";
}
}
bool AppConfig::isPremium()
{
QString hashSrc = m_PremiumEmail + getFirstMacAddress();
QString hashResult = hash(hashSrc);
return hashResult == m_PremiumToken;
}

View File

@ -30,9 +30,10 @@
// here...
//
// 1: first version
// 2: language page added
// 2: added language page
// 3: added premium page
//
const int kWizardVersion = 2;
const int kWizardVersion = 3;
class QSettings;
class SettingsDialog;
@ -70,6 +71,8 @@ class AppConfig
ProcessMode processMode() const { return m_ProcessMode; }
bool wizardShouldRun() const { return m_WizardLastRun < kWizardVersion; }
const QString& language() const { return m_Language; }
const QString& premiumEmail() const { return m_PremiumEmail; }
const QString& premiumToken() const { return m_PremiumToken; }
QString synergysName() const { return m_SynergysName; }
QString synergycName() const { return m_SynergycName; }
@ -78,6 +81,7 @@ class AppConfig
bool detectPath(const QString& name, QString& path);
void persistLogDir();
bool isPremium();
protected:
QSettings& settings() { return *m_pSettings; }
@ -95,12 +99,13 @@ class AppConfig
void setProcessMode(ProcessMode p) { m_ProcessMode = p; }
void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
void setLanguage(const QString language) { m_Language = language; }
void setPremiumEmail(const QString premiumEmail) { m_PremiumEmail = premiumEmail; }
void setPremiumToken(const QString premiumToken) { m_PremiumToken = premiumToken; }
void loadSettings();
void saveSettings();
void setCryptoPass(const QString& s);
static QString hash(const QString& string);
private:
QSettings* m_pSettings;
@ -119,6 +124,8 @@ class AppConfig
CryptoMode m_CryptoMode;
ProcessMode m_ProcessMode;
QString m_Language;
QString m_PremiumEmail;
QString m_PremiumToken;
static const char m_SynergysName[];
static const char m_SynergycName[];

View File

@ -28,3 +28,24 @@ void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
}
}
}
QString hash(const QString& string)
{
QByteArray data = string.toUtf8();
QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
return hash.toHex();
}
QString getFirstMacAddress()
{
QString mac;
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces())
{
mac = interface.hardwareAddress();
if (mac.size() != 0)
{
break;
}
}
return mac;
}

View File

@ -19,5 +19,9 @@
#include <QComboBox>
#include <QVariant>
#include <QCryptographicHash>
#include <QNetworkInterface>
void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData);
QString hash(const QString& string);
QString getFirstMacAddress();

View File

@ -24,7 +24,6 @@
#include <QtCore>
#include <QtGui>
#include <QCryptographicHash>
SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
@ -45,9 +44,19 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
m_pLineEditLogFilename->setText(appConfig().logFilename());
m_pCheckBoxAutoStart->setChecked(appConfig().autoStart());
m_pCheckBoxAutoHide->setChecked(appConfig().autoHide());
m_pComboCryptoMode->setCurrentIndex(getCryptoModeIndex(appConfig().cryptoMode()));
m_pLineEditCryptoPass->setText(appConfig().cryptoPass());
setIndexFromItemData(m_pComboLanguage, appConfig().language());
if (appConfig().isPremium())
{
m_pComboCryptoMode->setCurrentIndex(getCryptoModeIndex(appConfig().cryptoMode()));
m_pLineEditCryptoPass->setText(appConfig().cryptoPass());
}
else
{
int size = m_pComboCryptoMode->count();
m_pComboCryptoMode->setCurrentIndex(size - 1);
m_pComboCryptoMode->setEnabled(false);
}
}
void SettingsDialog::accept()

View File

@ -21,7 +21,12 @@
#include "QUtility.h"
#include <QMessageBox>
#include <iostream>
#include <QDesktopServices>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#define PREMIUM_AUTH_URL "https://synergy-foss.org/premium/json/auth/"
SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
m_MainWindow(mainWindow),
@ -52,6 +57,13 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
m_Locale.fillLanguageComboBox(m_pComboLanguage);
setIndexFromItemData(m_pComboLanguage, m_MainWindow.appConfig().language());
AppConfig& appConfig = m_MainWindow.appConfig();
QString premiumEmail = appConfig.premiumEmail();
if (!premiumEmail.isEmpty())
{
m_pRadioButtonPremiumLogin->setChecked(true);
m_pLineEditPremiumEmail->setText(premiumEmail);
}
}
SetupWizard::~SetupWizard()
@ -76,6 +88,46 @@ bool SetupWizard::validateCurrentPage()
return false;
}
}
else if (currentPage() == m_pPremiumUserPage)
{
if (m_pRadioButtonPremiumLogin->isChecked())
{
if (m_pLineEditPremiumEmail->text().isEmpty() ||
m_pLineEditPremiumPassword->text().isEmpty())
{
message.setText(tr("Please enter your email address and password."));
message.exec();
return false;
}
else if (!isPremiumLoginValid(message))
{
return false;
}
else
{
m_pComboCryptoMode->setCurrentIndex(0);
m_pComboCryptoMode->setEnabled(true);
}
}
else if (m_pRadioButtonPremiumRegister->isChecked())
{
const QUrl url(QString("https://synergy-foss.org/premium/register/"));
QDesktopServices::openUrl(url);
m_pRadioButtonPremiumLogin->setChecked(true);
return false;
}
else if (m_pRadioButtonPremiumLater->isChecked())
{
int size = m_pComboCryptoMode->count();
m_pComboCryptoMode->setCurrentIndex(size - 1);
m_pComboCryptoMode->setEnabled(false);
}
else {
message.setText(tr("Please select an option."));
message.exec();
return false;
}
}
else if (currentPage() == m_pCryptoPage)
{
QString modeText = m_pComboCryptoMode->currentText();
@ -88,14 +140,14 @@ bool SetupWizard::validateCurrentPage()
if (parseCryptoMode(modeText) != Disabled)
{
if (m_pLineEditCryptoPass->text().isEmpty())
if (m_pLineEditCryptoPassword1->text().isEmpty())
{
message.setText(tr("Encryption password required."));
message.exec();
return false;
}
if (m_pLineEditCryptoPass->text() != m_pLineEditCryptoPassConfirm->text())
if (m_pLineEditCryptoPassword1->text() != m_pLineEditCryptoPassword2->text())
{
message.setText(tr("Encryption password and confirmation do not match."));
message.exec();
@ -132,8 +184,21 @@ void SetupWizard::accept()
AppConfig& appConfig = m_MainWindow.appConfig();
appConfig.setCryptoMode(parseCryptoMode(m_pComboCryptoMode->currentText()));
appConfig.setCryptoPass(m_pLineEditCryptoPass->text());
appConfig.setCryptoPass(m_pLineEditCryptoPassword1->text());
appConfig.setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
appConfig.setPremiumEmail(m_pLineEditPremiumEmail->text());
if (!m_pRadioButtonPremiumLogin->isChecked())
{
appConfig.setPremiumToken("");
}
else
{
QString mac = getFirstMacAddress();
QString hashSrc = m_pLineEditPremiumEmail->text() + mac;
QString hashResult = hash(hashSrc);
appConfig.setPremiumToken(hashResult);
}
appConfig.setWizardHasRun();
appConfig.saveSettings();
@ -163,14 +228,20 @@ void SetupWizard::accept()
void SetupWizard::reject()
{
QSynergyApplication::getInstance()->switchTranslator(m_MainWindow.appConfig().language());
if (m_StartMain)
{
m_MainWindow.start(true);
}
QWizard::reject();
}
void SetupWizard::on_m_pComboCryptoMode_currentIndexChanged(int index)
{
bool enabled = parseCryptoMode(m_pComboCryptoMode->currentText()) != Disabled;
m_pLineEditCryptoPass->setEnabled(enabled);
m_pLineEditCryptoPassConfirm->setEnabled(enabled);
m_pLineEditCryptoPassword1->setEnabled(enabled);
m_pLineEditCryptoPassword2->setEnabled(enabled);
}
CryptoMode SetupWizard::parseCryptoMode(const QString& s)
@ -200,3 +271,51 @@ void SetupWizard::on_m_pComboLanguage_currentIndexChanged(int index)
QString ietfCode = m_pComboLanguage->itemData(index).toString();
QSynergyApplication::getInstance()->switchTranslator(ietfCode);
}
void SetupWizard::on_m_pRadioButtonPremiumLogin_toggled(bool checked)
{
m_pLineEditPremiumEmail->setEnabled(checked);
m_pLineEditPremiumPassword->setEnabled(checked);
}
bool SetupWizard::isPremiumLoginValid(QMessageBox& message)
{
QString email = m_pLineEditPremiumEmail->text();
QString password = m_pLineEditPremiumPassword->text();
QString requestJson = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\"}";
QByteArray requestData(requestJson.toStdString().c_str());
QNetworkRequest request(QUrl(PREMIUM_AUTH_URL));
QUrl params;
params.addEncodedQueryItem("json", requestData);
QNetworkReply* reply = m_Network.post(request, params.encodedQuery());
// use loop instead of waitForReadyRead (which doesnt seem to work).
QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
QByteArray responseData = reply->readAll();
QString responseJson(responseData);
// this feels like a lot of work, but its cheaper than getting a json
// parsing library involved.
QRegExp regex(".*\"result\":\\s*([^,}\\s]+).*");
if (regex.exactMatch(responseJson)) {
QString boolString = regex.cap(1);
if (boolString == "true") {
return true;
}
else if (boolString == "false") {
message.setText(tr("Login failed, invalid email or password."));
message.exec();
return false;
}
}
message.setText(tr("Login failed, an error occurred."));
message.exec();
return false;
}

View File

@ -17,12 +17,15 @@
#pragma once
#include <QWizard>
#include "ui_SetupWizardBase.h"
#include "CryptoMode.h"
#include "SynergyLocale.h"
#include <QWizard>
#include <QNetworkAccessManager>
class MainWindow;
class QMessageBox;
class SetupWizard : public QWizard, public Ui::SetupWizardBase
{
@ -39,13 +42,16 @@ protected:
private:
CryptoMode parseCryptoMode(const QString& s);
bool isPremiumLoginValid(QMessageBox& message);
private:
MainWindow& m_MainWindow;
bool m_StartMain;
SynergyLocale m_Locale;
QNetworkAccessManager m_Network;
private slots:
void on_m_pComboCryptoMode_currentIndexChanged(int index);
void on_m_pComboLanguage_currentIndexChanged(int index);
void on_m_pRadioButtonPremiumLogin_toggled(bool checked);
};