+#include
+
+class AppConfig;
+
+class LicenseManager: public QObject
+{
+ Q_OBJECT
+
+public:
+ LicenseManager(AppConfig* appConfig);
+ std::pair setSerialKey(QString serialKey, bool acceptExpired = false);
+ void refresh();
+ Edition activeEdition() const;
+ QString activeEditionName() const;
+ SerialKey serialKey() const;
+ void skipActivation();
+ void notifyUpdate(QString fromVersion, QString toVersion);
+ static QString getEditionName(Edition edition, bool trial = false);
+ void notifyActivation(QString identity);
+
+private:
+ AppConfig* m_AppConfig;
+ SerialKey m_serialKey;
+
+signals:
+ void serialKeyChanged (SerialKey) const;
+ void editionChanged (Edition) const;
+ void beginTrial (bool expiring) const;
+ void endTrial (bool expired) const;
+};
diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp
index f9903a12..f32ebdc8 100644
--- a/src/gui/src/MainWindow.cpp
+++ b/src/gui/src/MainWindow.cpp
@@ -30,7 +30,7 @@
#include "ZeroconfService.h"
#include "DataDownloader.h"
#include "CommandProcess.h"
-#include "SubscriptionManager.h"
+#include "LicenseManager.h"
#include "EditionType.h"
#include "QUtility.h"
#include "ProcessorArch.h"
@@ -76,12 +76,14 @@ static const char* synergyIconFiles[] =
":/res/icons/16x16/synergy-transfering.png"
};
-MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
+MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
+ LicenseManager& licenseManager) :
m_Settings(settings),
- m_AppConfig(appConfig),
+ m_AppConfig(&appConfig),
+ m_LicenseManager(&licenseManager),
m_pSynergy(NULL),
m_SynergyState(synergyDisconnected),
- m_ServerConfig(&m_Settings, 5, 3, m_AppConfig.screenName(), this),
+ m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this),
m_pTempConfigFile(NULL),
m_pTrayIcon(NULL),
m_pTrayIconMenu(NULL),
@@ -99,7 +101,8 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_BonjourInstall(NULL),
m_SuppressEmptyServerWarning(false),
m_ExpectedRunningState(kStopped),
- m_pSslCertificate(NULL)
+ m_pSslCertificate(NULL),
+ m_ActivationDialogRunning(false)
{
setupUi(this);
@@ -134,13 +137,34 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_SuppressAutoConfigWarning = false;
m_pComboServerList->hide();
-
- setEdition(m_AppConfig.edition());
-
m_pLabelPadlock->hide();
- connect (this, SIGNAL(windowShown()), this, SLOT(on_windowShown()), Qt::QueuedConnection);
- connect (&m_AppConfig, SIGNAL(editionSet(int)), this, SLOT(setEdition(int)), Qt::QueuedConnection);
- connect (&m_AppConfig, SIGNAL(sslToggled(bool)), this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
+ m_trialWidget->hide();
+
+ connect (this, SIGNAL(windowShown()),
+ this, SLOT(on_windowShown()), Qt::QueuedConnection);
+
+ connect (m_LicenseManager, SIGNAL(editionChanged(Edition)),
+ this, SLOT(setEdition(Edition)), Qt::QueuedConnection);
+
+ connect (m_LicenseManager, SIGNAL(beginTrial(bool)),
+ this, SLOT(beginTrial(bool)), Qt::QueuedConnection);
+
+ connect (m_LicenseManager, SIGNAL(endTrial(bool)),
+ this, SLOT(endTrial(bool)), Qt::QueuedConnection);
+
+ connect (m_AppConfig, SIGNAL(sslToggled(bool)),
+ this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
+
+ setWindowTitle (m_LicenseManager->activeEditionName());
+ m_LicenseManager->refresh();
+
+ QString lastVersion = m_AppConfig->lastVersion();
+ QString currentVersion = m_VersionChecker.getVersion();
+ if (lastVersion != currentVersion) {
+ m_AppConfig->setLastVersion (currentVersion);
+ m_AppConfig->saveSettings();
+ m_LicenseManager->notifyUpdate (lastVersion, currentVersion);
+ }
}
MainWindow::~MainWindow()
@@ -397,15 +421,17 @@ void MainWindow::appendLogRaw(const QString& text)
foreach(QString line, text.split(QRegExp("\r|\n|\r\n"))) {
if (!line.isEmpty()) {
m_pLogOutput->append(line);
- updateStateFromLogLine(line);
+ updateFromLogLine(line);
}
}
}
-void MainWindow::updateStateFromLogLine(const QString &line)
+void MainWindow::updateFromLogLine(const QString &line)
{
+ // TODO: this code makes Andrew cry
checkConnected(line);
checkFingerprint(line);
+ checkLicense(line);
}
void MainWindow::checkConnected(const QString& line)
@@ -430,6 +456,14 @@ void MainWindow::checkConnected(const QString& line)
}
}
+void MainWindow::checkLicense(const QString &line)
+{
+ if (line.contains("trial has expired")) {
+ licenseManager().refresh();
+ raiseActivationDialog();
+ }
+}
+
void MainWindow::checkFingerprint(const QString& line)
{
QRegExp fingerprintRegex(".*server fingerprint: ([A-F0-9:]+)");
@@ -498,7 +532,7 @@ void MainWindow::restartSynergy()
void MainWindow::proofreadInfo()
{
- setEdition(m_AppConfig.edition()); // Why is this here?
+ setEdition(m_AppConfig->edition()); // Why is this here?
int oldState = m_SynergyState;
m_SynergyState = synergyDisconnected;
@@ -518,6 +552,14 @@ void MainWindow::clearLog()
void MainWindow::startSynergy()
{
+ SerialKey serialKey = m_LicenseManager->serialKey();
+ time_t currentTime = ::time(0);
+ if (serialKey.isExpired(currentTime)) {
+ if (QDialog::Rejected == raiseActivationDialog()) {
+ return;
+ }
+ }
+
bool desktopMode = appConfig().processMode() == Desktop;
bool serviceMode = appConfig().processMode() == Service;
@@ -566,7 +608,7 @@ void MainWindow::startSynergy()
#endif
- if (m_AppConfig.getCryptoEnabled()) {
+ if (m_AppConfig->getCryptoEnabled()) {
args << "--enable-crypto";
}
@@ -734,19 +776,6 @@ QString MainWindow::appPath(const QString& name)
bool MainWindow::serverArgs(QStringList& args, QString& app)
{
- int edition;
- SubscriptionManager subscriptionManager(this, appConfig(), edition);
- if (subscriptionManager.fileExists())
- {
- if (!subscriptionManager.checkSubscription()) {
- return false;
- }
- else {
- setEdition(edition);
- }
- }
-
-
app = appPath(appConfig().synergysName());
if (!QFile::exists(app))
@@ -775,6 +804,10 @@ bool MainWindow::serverArgs(QStringList& args, QString& app)
#endif
args << "-c" << configFilename << "--address" << address();
+ if (!appConfig().serialKey().isEmpty()) {
+ args << "--serial-key" << appConfig().serialKey();
+ }
+
#if defined(Q_OS_WIN)
// pass in physical resolution and primary screen center
// TODO: get this information in the core binary even when
@@ -895,7 +928,7 @@ void MainWindow::setSynergyState(qSynergyState state)
switch (state)
{
case synergyConnected: {
- if (m_AppConfig.getCryptoEnabled()) {
+ if (m_AppConfig->getCryptoEnabled()) {
m_pLabelPadlock->show();
}
else {
@@ -1010,13 +1043,13 @@ void MainWindow::updateZeroconfService()
QMutexLocker locker(&m_UpdateZeroconfMutex);
if (isBonjourRunning()) {
- if (!m_AppConfig.wizardShouldRun()) {
+ if (!m_AppConfig->wizardShouldRun()) {
if (m_pZeroconfService) {
delete m_pZeroconfService;
m_pZeroconfService = NULL;
}
- if (m_AppConfig.autoConfig() || synergyType() == synergyServer) {
+ if (m_AppConfig->autoConfig() || synergyType() == synergyServer) {
m_pZeroconfService = new ZeroconfService(this);
}
}
@@ -1035,10 +1068,10 @@ void MainWindow::serverDetected(const QString name)
}
}
-void MainWindow::setEdition(int edition)
+void MainWindow::setEdition(Edition edition)
{
- setWindowTitle(getEditionName(edition));
- if (m_AppConfig.getCryptoEnabled()) {
+ setWindowTitle(m_LicenseManager->getEditionName (edition));
+ if (m_AppConfig->getCryptoEnabled()) {
m_pSslCertificate = new SslCertificate(this);
m_pSslCertificate->generateCertificate();
}
@@ -1046,9 +1079,60 @@ void MainWindow::setEdition(int edition)
saveSettings();
}
+void MainWindow::beginTrial(bool isExpiring)
+{
+ //Hack
+ //if (isExpiring) {
+ time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
+ QString expiringNotice ("%1 day%3 of "
+ "your %2 trial remain%5. "
+ "Buy now!"
+ "
");
+ expiringNotice = expiringNotice
+ .arg (daysLeft)
+ .arg (LicenseManager::getEditionName
+ (m_LicenseManager->activeEdition()))
+ .arg ((daysLeft == 1) ? "" : "s")
+ .arg (QString::fromStdString
+ (m_LicenseManager->serialKey().toString()))
+ .arg ((daysLeft == 1) ? "s" : "");
+ this->m_trialLabel->setText(expiringNotice);
+ this->m_trialWidget->show();
+ //}
+ setWindowTitle (m_LicenseManager->activeEditionName());
+}
+
+void MainWindow::endTrial(bool isExpired)
+{
+ if (isExpired) {
+ QString expiredNotice (
+ "Your %1 trial has expired. "
+ ""
+ "Buy now!
"
+ );
+ expiredNotice = expiredNotice
+ .arg(LicenseManager::getEditionName
+ (m_LicenseManager->activeEdition()))
+ .arg(QString::fromStdString
+ (m_LicenseManager->serialKey().toString()));
+
+ this->m_trialLabel->setText(expiredNotice);
+ this->m_trialWidget->show();
+ stopSynergy();
+ m_AppConfig->activationHasRun(false);
+ } else {
+ this->m_trialWidget->hide();
+ }
+ setWindowTitle (m_LicenseManager->activeEditionName());
+}
+
void MainWindow::updateLocalFingerprint()
{
- if (m_AppConfig.getCryptoEnabled() && Fingerprint::local().fileExists()) {
+ if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists()) {
m_pLabelFingerprint->setVisible(true);
m_pLabelLocalFingerprint->setVisible(true);
m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst());
@@ -1059,6 +1143,12 @@ void MainWindow::updateLocalFingerprint()
}
}
+LicenseManager&
+MainWindow::licenseManager() const
+{
+ return *m_LicenseManager;
+}
+
void MainWindow::on_m_pGroupClient_toggled(bool on)
{
m_pGroupServer->setChecked(!on);
@@ -1123,6 +1213,14 @@ void MainWindow::on_m_pActionSettings_triggered()
void MainWindow::autoAddScreen(const QString name)
{
if (!m_ServerConfig.ignoreAutoConfigClient()) {
+ if (m_ActivationDialogRunning) {
+ // TODO: refactor this code
+ // add this screen to the pending list and check this list until
+ // users finish activation dialog
+ m_PendingClientNames.append(name);
+ return;
+ }
+
int r = m_ServerConfig.autoAddScreen(name);
if (r != kAutoAddScreenOk) {
switch (r) {
@@ -1160,8 +1258,7 @@ void MainWindow::on_m_pButtonConfigureServer_clicked()
void MainWindow::on_m_pActivate_triggered()
{
- ActivationDialog activationDialog (this, this->appConfig());
- activationDialog.exec();
+ raiseActivationDialog();
}
void MainWindow::on_m_pButtonApply_clicked()
@@ -1321,16 +1418,16 @@ void MainWindow::promptAutoConfig()
QMessageBox::Yes | QMessageBox::No);
if (r == QMessageBox::Yes) {
- m_AppConfig.setAutoConfig(true);
+ m_AppConfig->setAutoConfig(true);
downloadBonjour();
}
else {
- m_AppConfig.setAutoConfig(false);
+ m_AppConfig->setAutoConfig(false);
m_pCheckBoxAutoConfig->setChecked(false);
}
}
- m_AppConfig.setAutoConfigPrompted(true);
+ m_AppConfig->setAutoConfigPrompted(true);
}
void MainWindow::on_m_pComboServerList_currentIndexChanged(QString )
@@ -1376,11 +1473,37 @@ void MainWindow::bonjourInstallFinished()
m_pCheckBoxAutoConfig->setChecked(true);
}
+int MainWindow::raiseActivationDialog()
+{
+ if (m_ActivationDialogRunning) {
+ return QDialog::Rejected;
+ }
+ ActivationDialog activationDialog (this, appConfig(), licenseManager());
+ m_ActivationDialogRunning = true;
+ connect (&activationDialog, SIGNAL(finished(int)),
+ this, SLOT(on_activationDialogFinish()), Qt::QueuedConnection);
+ int result = activationDialog.exec();
+ m_ActivationDialogRunning = false;
+ if (!m_PendingClientNames.empty()) {
+ foreach (const QString& name, m_PendingClientNames) {
+ autoAddScreen(name);
+ }
+
+ m_PendingClientNames.clear();
+ }
+ if (result == QDialog::Accepted) {
+ restartSynergy();
+ }
+ return result;
+}
+
void MainWindow::on_windowShown()
{
- if (!m_AppConfig.activationHasRun() && (m_AppConfig.edition() == Unregistered)) {
- ActivationDialog activationDialog (this, m_AppConfig);
- activationDialog.exec();
+ time_t currentTime = ::time(0);
+ if (!m_AppConfig->activationHasRun()
+ && ((m_AppConfig->edition() == kUnregistered) ||
+ (m_LicenseManager->serialKey().isExpired(currentTime)))) {
+ raiseActivationDialog();
}
}
diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h
index efd83dcc..2ca3e711 100644
--- a/src/gui/src/MainWindow.h
+++ b/src/gui/src/MainWindow.h
@@ -58,6 +58,7 @@ class ZeroconfService;
class DataDownloader;
class CommandProcess;
class SslCertificate;
+class LicenseManager;
class MainWindow : public QMainWindow, public Ui::MainWindowBase
{
@@ -67,7 +68,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
friend class SetupWizard;
friend class ActivationDialog;
friend class SettingsDialog;
-
+
public:
enum qSynergyState
{
@@ -94,7 +95,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
};
public:
- MainWindow(QSettings& settings, AppConfig& appConfig);
+ MainWindow(QSettings& settings, AppConfig& appConfig,
+ LicenseManager& licenseManager);
~MainWindow();
public:
@@ -116,9 +118,14 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void updateZeroconfService();
void serverDetected(const QString name);
void updateLocalFingerprint();
+ LicenseManager& licenseManager() const;
- public slots:
- void setEdition(int edition);
+ int raiseActivationDialog();
+
+public slots:
+ void setEdition(Edition edition);
+ void beginTrial(bool isExpiring);
+ void endTrial(bool isExpired);
void appendLogRaw(const QString& text);
void appendLogInfo(const QString& text);
void appendLogDebug(const QString& text);
@@ -145,7 +152,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
protected:
QSettings& settings() { return m_Settings; }
- AppConfig& appConfig() { return m_AppConfig; }
+ AppConfig& appConfig() { return *m_AppConfig; }
QProcess* synergyProcess() { return m_pSynergy; }
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
void initConnections();
@@ -162,7 +169,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void setStatus(const QString& status);
void sendIpcMessage(qIpcMessageType type, const char* buffer, bool showErrors);
void onModeChanged(bool startDesktop, bool applyService);
- void updateStateFromLogLine(const QString& line);
+ void updateFromLogLine(const QString& line);
QString getIPAddresses();
void stopService();
void stopDesktop();
@@ -178,6 +185,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void promptAutoConfig();
QString getProfileRootForArg();
void checkConnected(const QString& line);
+ void checkLicense(const QString& line);
void checkFingerprint(const QString& line);
bool autoHide();
QString getTimeStamp();
@@ -188,7 +196,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
private:
QSettings& m_Settings;
- AppConfig& m_AppConfig;
+ AppConfig* m_AppConfig;
+ LicenseManager* m_LicenseManager;
QProcess* m_pSynergy;
int m_SynergyState;
ServerConfig m_ServerConfig;
@@ -214,6 +223,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
qRuningState m_ExpectedRunningState;
QMutex m_StopDesktopMutex;
SslCertificate* m_pSslCertificate;
+ bool m_ActivationDialogRunning;
+ QStringList m_PendingClientNames;
private slots:
void on_m_pCheckBoxAutoConfig_toggled(bool checked);
diff --git a/src/gui/src/QUtility.cpp b/src/gui/src/QUtility.cpp
index f463f1d2..589e74cf 100644
--- a/src/gui/src/QUtility.cpp
+++ b/src/gui/src/QUtility.cpp
@@ -43,22 +43,6 @@ void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
}
}
-QString
-getEditionName (int edition) {
- if (edition == Basic) {
- return "Synergy Basic";
- }
- else if (edition == Pro) {
- return "Synergy Pro";
- }
- else if (edition == Trial) {
- return "Synergy Trial";
- }
- else {
- return "Synergy (UNREGISTERED)";
- }
-}
-
QString hash(const QString& string)
{
QByteArray data = string.toUtf8();
diff --git a/src/gui/src/QUtility.h b/src/gui/src/QUtility.h
index ca00d06f..0738d96c 100644
--- a/src/gui/src/QUtility.h
+++ b/src/gui/src/QUtility.h
@@ -29,4 +29,3 @@ QString hash(const QString& string);
QString getFirstMacAddress();
qProcessorArch getProcessorArch();
QString getOSInformation();
-QString getEditionName (int edition);
diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp
index 9b1d1b0e..ddbeae4d 100644
--- a/src/gui/src/SettingsDialog.cpp
+++ b/src/gui/src/SettingsDialog.cpp
@@ -64,7 +64,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
#endif
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
- m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == Pro);
+ m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == kPro);
}
void SettingsDialog::accept()
diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp
index b4e6ab3a..da3ff8c3 100644
--- a/src/gui/src/SetupWizard.cpp
+++ b/src/gui/src/SetupWizard.cpp
@@ -19,7 +19,7 @@
#include "MainWindow.h"
#include "WebClient.h"
#include "ActivationNotifier.h"
-#include "SubscriptionManager.h"
+#include "LicenseManager.h"
#include "EditionType.h"
#include "QSynergyApplication.h"
#include "QUtility.h"
diff --git a/src/gui/src/SubscriptionManager.cpp b/src/gui/src/SubscriptionManager.cpp
deleted file mode 100644
index 77e0a91c..00000000
--- a/src/gui/src/SubscriptionManager.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * synergy -- mouse and keyboard sharing utility
- * Copyright (C) 2015 Synergy Seamless Inc.
- *
- * 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 LICENSE 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 .
- */
-
-#include "SubscriptionManager.h"
-
-
-#include "CoreInterface.h"
-#include "EditionType.h"
-#include "AppConfig.h"
-
-#include
-#include
-#include
-#include
-#include
-
-static const char purchaseURL[] = "https://symless.com/account/";
-
-SubscriptionManager::SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition) :
- m_pParent(parent),
- m_AppConfig(appConfig),
- m_Edition(edition)
-{
-}
-
-bool SubscriptionManager::activateSerial(const QString& serial)
-{
- m_Edition = Unregistered;
- persistDirectory();
- CoreInterface coreInterface;
- QString output;
-
- try
- {
- output = coreInterface.activateSerial(serial);
- }
- catch (std::exception& e)
- {
- m_ErrorMessage = e.what();
- checkError(m_ErrorMessage);
- return false;
- }
-
- checkOutput(output);
-
- return true;
-}
-
-bool SubscriptionManager::checkSubscription()
-{
- m_Edition = Unregistered;
- persistDirectory();
- CoreInterface coreInterface;
- QString output;
- try
- {
- output = coreInterface.checkSubscription();
- }
- catch (std::exception& e)
- {
- m_ErrorMessage = e.what();
- checkError(m_ErrorMessage);
- return false;
- }
-
- checkOutput(output);
-
- return true;
-}
-
-bool SubscriptionManager::fileExists()
-{
- CoreInterface coreInterface;
- QString subscriptionFilename = coreInterface.getSubscriptionFilename();
-
- return QFile::exists(subscriptionFilename);
-}
-
-void SubscriptionManager::checkError(QString& error)
-{
- if (error.contains("trial has expired")) {
- QMessageBox::warning(m_pParent, tr("Subscription warning"),
- tr("Your trial has expired. Click here to purchase").arg(purchaseURL));
- }
- else {
- QMessageBox::warning(m_pParent, tr("Subscription error"),
- tr("An error occurred while trying to activate Synergy using your serial key. "
- "Please contact the helpdesk, and provide the "
- "following details.\n\n%1").arg(error));
- }
-}
-
-void SubscriptionManager::checkOutput(QString& output)
-{
- getEditionType(output);
- checkExpiring(output);
-}
-
-void SubscriptionManager::getEditionType(QString& output)
-{
- if (output.contains("pro subscription valid")) {
- m_Edition = Pro;
- }
- else if (output.contains("basic subscription valid")) {
- m_Edition = Basic;
- }
- else if (output.contains("trial subscription valid")) {
- m_Edition = Trial;
- }
-}
-
-void SubscriptionManager::checkExpiring(QString& output)
-{
- if (output.contains("trial will end in") && shouldWarnExpiring()) {
- QRegExp dayLeftRegex(".*trial will end in ([0-9]+) day.*");
- if (dayLeftRegex.exactMatch(output)) {
- QString dayLeft = dayLeftRegex.cap(1);
-
- QMessageBox::warning(m_pParent, tr("Subscription warning"),
- tr("Your trial will end in %1 %2. Click here to purchase")
- .arg(dayLeft)
- .arg(dayLeft == "1" ? "day" : "days")
- .arg(purchaseURL));
- }
- }
-}
-
-bool SubscriptionManager::shouldWarnExpiring()
-{
- // warn users about expiring subscription once a day
- int lastExpiringWarningTime = m_AppConfig.lastExpiringWarningTime();
- QDateTime currentDateTime = QDateTime::currentDateTime();
- int currentTime = currentDateTime.toTime_t();
- const int secondPerDay = 60 * 60 * 24;
- bool result = false;
- if ((currentTime - lastExpiringWarningTime) > secondPerDay) {
- result = true;
- m_AppConfig.setLastExpiringWarningTime(currentTime);
- }
-
- return result;
-}
-
-void SubscriptionManager::persistDirectory()
-{
- CoreInterface coreInterface;
- QString profileDir = coreInterface.getProfileDir();
-
- QDir dir(profileDir);
- if (!dir.exists()) {
- dir.mkpath(".");
- }
-}
diff --git a/src/gui/src/SubscriptionManager.h b/src/gui/src/SubscriptionManager.h
deleted file mode 100644
index 59497352..00000000
--- a/src/gui/src/SubscriptionManager.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * synergy -- mouse and keyboard sharing utility
- * Copyright (C) 2015 Synergy Seamless Inc.
- *
- * 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 LICENSE 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 .
- */
-
-#pragma once
-
-#include
-
-class AppConfig;
-
-class SubscriptionManager : public QWidget
-{
-public:
- SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition);
-
- bool activateSerial(const QString& serial);
- bool checkSubscription();
- bool fileExists();
- QString getLastError(){ return m_ErrorMessage; }
-
-private:
- void checkError(QString& error);
- void checkOutput(QString& output);
- void getEditionType(QString& output);
- void checkExpiring(QString& output);
- bool shouldWarnExpiring();
- void persistDirectory();
-
-private:
- QString m_ErrorMessage;
- QWidget* m_pParent;
- AppConfig& m_AppConfig;
- int& m_Edition;
-};
diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp
index 0ea2cbfe..d36db755 100644
--- a/src/gui/src/main.cpp
+++ b/src/gui/src/main.cpp
@@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de)
- *
+ *
* 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 LICENSE 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
@@ -20,6 +20,7 @@
#define TRAY_RETRY_WAIT 2000
#include "QSynergyApplication.h"
+#include "LicenseManager.h"
#include "MainWindow.h"
#include "AppConfig.h"
#include "SetupWizard.h"
@@ -65,7 +66,7 @@ int main(int argc, char* argv[])
"Please drag Synergy to the Applications folder, and open it from there.");
return 1;
}
-
+
if (!checkMacAssistiveDevices())
{
return 1;
@@ -82,11 +83,13 @@ int main(int argc, char* argv[])
#endif
QSettings settings;
- AppConfig appConfig(&settings);
+ AppConfig appConfig (&settings);
+ qRegisterMetaType("Edition");
+ LicenseManager licenseManager (&appConfig);
app.switchTranslator(appConfig.language());
- MainWindow mainWindow(settings, appConfig);
+ MainWindow mainWindow(settings, appConfig, licenseManager);
SetupWizard setupWizard(mainWindow, true);
if (appConfig.wizardShouldRun())
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 48beb80a..f53d9db8 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -25,7 +25,7 @@ add_subdirectory(net)
add_subdirectory(platform)
add_subdirectory(server)
add_subdirectory(synergy)
-
+add_subdirectory(shared)
if (WIN32)
add_subdirectory(synwinhk)
diff --git a/src/lib/arch/unix/ArchInternetUnix.cpp b/src/lib/arch/unix/ArchInternetUnix.cpp
index 596000c1..fe4a39ba 100644
--- a/src/lib/arch/unix/ArchInternetUnix.cpp
+++ b/src/lib/arch/unix/ArchInternetUnix.cpp
@@ -116,7 +116,6 @@ CurlFacade::urlEncode(const String& url)
char* resultCStr = curl_easy_escape(m_curl, url.c_str(), 0);
if (resultCStr == NULL) {
- curl_free(resultCStr);
throw XArch("CURL escape failed.");
}
diff --git a/src/lib/net/IListenSocket.h b/src/lib/net/IListenSocket.h
index 905ec831..2cd6fb1b 100644
--- a/src/lib/net/IListenSocket.h
+++ b/src/lib/net/IListenSocket.h
@@ -41,14 +41,7 @@ public:
*/
virtual IDataSocket*
accept() = 0;
-
- //! Delete connection socket
- /*!
- This is used when the socket was created but not adopted by a client
- proxy.
- */
- virtual void deleteSocket(void*) = 0;
-
+
//@}
// ISocket overrides
diff --git a/src/lib/net/SecureListenSocket.cpp b/src/lib/net/SecureListenSocket.cpp
index b4c08646..533ae41a 100644
--- a/src/lib/net/SecureListenSocket.cpp
+++ b/src/lib/net/SecureListenSocket.cpp
@@ -93,14 +93,3 @@ SecureListenSocket::accept()
throw ex;
}
}
-
-void
-SecureListenSocket::deleteSocket(void* socket)
-{
- SecureSocketSet::iterator it;
- it = m_secureSocketSet.find((IDataSocket*)socket);
- if (it != m_secureSocketSet.end()) {
- delete *it;
- m_secureSocketSet.erase(it);
- }
-}
diff --git a/src/lib/net/SecureListenSocket.h b/src/lib/net/SecureListenSocket.h
index ff19602c..960a8a26 100644
--- a/src/lib/net/SecureListenSocket.h
+++ b/src/lib/net/SecureListenSocket.h
@@ -33,7 +33,6 @@ public:
// IListenSocket overrides
virtual IDataSocket*
accept();
- void deleteSocket(void*);
private:
typedef std::set SecureSocketSet;
diff --git a/src/lib/net/TCPListenSocket.h b/src/lib/net/TCPListenSocket.h
index cf4469a0..41308622 100644
--- a/src/lib/net/TCPListenSocket.h
+++ b/src/lib/net/TCPListenSocket.h
@@ -43,7 +43,6 @@ public:
// IListenSocket overrides
virtual IDataSocket*
accept();
- virtual void deleteSocket(void*) { }
protected:
void setListeningJob();
diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt
index 6c272c21..481d8ef9 100644
--- a/src/lib/platform/CMakeLists.txt
+++ b/src/lib/platform/CMakeLists.txt
@@ -19,7 +19,7 @@ if (WIN32)
file(GLOB sources "MSWindows*.cpp")
elseif (APPLE)
file(GLOB headers "OSX*.h" "IOSX*.h")
- file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m")
+ file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m" "OSX*.mm")
elseif (UNIX)
file(GLOB headers "XWindows*.h")
file(GLOB sources "XWindows*.cpp")
diff --git a/src/lib/platform/OSXClipboard.cpp b/src/lib/platform/OSXClipboard.cpp
index 84f7c7ce..7dae2081 100644
--- a/src/lib/platform/OSXClipboard.cpp
+++ b/src/lib/platform/OSXClipboard.cpp
@@ -122,7 +122,7 @@ OSXClipboard::add(EFormat format, const String & data)
PasteboardPutItemFlavor(
m_pboard,
- (PasteboardItemID) 0,
+ nullptr,
flavorType,
dataRef,
kPasteboardFlavorNoFlags);
diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h
index dce5ac08..0357583e 100644
--- a/src/lib/platform/OSXScreen.h
+++ b/src/lib/platform/OSXScreen.h
@@ -344,4 +344,6 @@ private:
Mutex* m_carbonLoopMutex;
CondVar* m_carbonLoopReady;
#endif
+
+ class OSXScreenImpl* m_impl;
};
diff --git a/src/lib/platform/OSXScreen.cpp b/src/lib/platform/OSXScreen.mm
similarity index 99%
rename from src/lib/platform/OSXScreen.cpp
rename to src/lib/platform/OSXScreen.mm
index e81f1621..2c2e66d6 100644
--- a/src/lib/platform/OSXScreen.cpp
+++ b/src/lib/platform/OSXScreen.mm
@@ -45,6 +45,8 @@
#include
#include
+#import
+
// Set some enums for fast user switching if we're building with an SDK
// from before such support was added.
#if !defined(MAC_OS_X_VERSION_10_3) || \
@@ -112,7 +114,8 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso
m_lastSingleClickYCursor(0),
m_autoShowHideCursor(autoShowHideCursor),
m_events(events),
- m_getDropTargetThread(NULL)
+ m_getDropTargetThread(NULL),
+ m_impl(NULL)
{
try {
m_displayID = CGMainDisplayID();
@@ -526,9 +529,7 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press)
// we define our own defaults.
const double maxDiff = sqrt(2) + 0.0001;
-
- NXEventHandle handle = NXOpenEventStatus();
- double clickTime = NXClickTime(handle);
+ double clickTime = [NSEvent doubleClickInterval];
// As long as the click is within the time window and distance window
// increase clickState (double click, triple click, etc)
diff --git a/src/lib/server/CMakeLists.txt b/src/lib/server/CMakeLists.txt
index 2c34af07..3cb582ec 100644
--- a/src/lib/server/CMakeLists.txt
+++ b/src/lib/server/CMakeLists.txt
@@ -35,6 +35,8 @@ endif()
add_library(server STATIC ${sources})
+target_link_libraries(server shared)
+
if (UNIX)
target_link_libraries(server synergy)
endif()
diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp
index 619ba2a0..a8bef7cf 100644
--- a/src/lib/server/ClientListener.cpp
+++ b/src/lib/server/ClientListener.cpp
@@ -106,12 +106,6 @@ ClientListener::setServer(Server* server)
m_server = server;
}
-void
-ClientListener::deleteSocket(void* socket)
-{
- m_listen->deleteSocket(socket);
-}
-
ClientProxy*
ClientListener::getNextClient()
{
@@ -213,10 +207,6 @@ ClientListener::handleUnknownClient(const Event&, void* vclient)
}
delete unknownClient;
-
- if (m_useSecureNetwork && !handshakeOk) {
- deleteSocket(socket);
- }
}
void
diff --git a/src/lib/server/ClientListener.h b/src/lib/server/ClientListener.h
index 7674386c..545e163a 100644
--- a/src/lib/server/ClientListener.h
+++ b/src/lib/server/ClientListener.h
@@ -48,8 +48,6 @@ public:
//@}
- void deleteSocket(void* socket);
-
//! @name accessors
//@{
diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp
index d9394ed5..ec730bcd 100644
--- a/src/lib/server/Server.cpp
+++ b/src/lib/server/Server.cpp
@@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
- *
+ *
* 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 LICENSE 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
@@ -45,11 +45,13 @@
#include "base/Log.h"
#include "base/TMethodEventJob.h"
#include "common/stdexcept.h"
+#include "shared/SerialKey.h"
#include
#include
#include
#include
+#include
//
// Server
@@ -60,7 +62,7 @@ Server::Server(
PrimaryClient* primaryClient,
synergy::Screen* screen,
IEventQueue* events,
- bool enableDragDrop) :
+ ServerArgs const& args) :
m_mock(false),
m_primaryClient(primaryClient),
m_active(primaryClient),
@@ -91,10 +93,10 @@ Server::Server(
m_sendFileThread(NULL),
m_writeToDropDirThread(NULL),
m_ignoreFileTransfer(false),
- m_enableDragDrop(enableDragDrop),
m_enableClipboard(true),
m_sendDragInfoThread(NULL),
- m_waitDragInfoThread(true)
+ m_waitDragInfoThread(true),
+ m_args(args)
{
// must have a primary client and it must have a canonical name
assert(m_primaryClient != NULL);
@@ -184,7 +186,7 @@ Server::Server(
new TMethodEventJob(this,
&Server::handleFakeInputEndEvent));
- if (m_enableDragDrop) {
+ if (m_args.m_enableDragDrop) {
m_events->adoptHandler(m_events->forFile().fileChunkSending(),
this,
new TMethodEventJob(this,
@@ -451,6 +453,13 @@ Server::switchScreen(BaseClientProxy* dst,
SInt32 x, SInt32 y, bool forScreensaver)
{
assert(dst != NULL);
+
+ // if trial is expired, exit the process
+ if (m_args.m_serial.isExpired(std::time(0))) {
+ LOG((CLOG_ERR "trial has expired, aborting server"));
+ exit(kExitSuccess);
+ }
+
#ifndef NDEBUG
{
SInt32 dx, dy, dw, dh;
@@ -534,7 +543,7 @@ Server::jumpToScreen(BaseClientProxy* newScreen)
// get the last cursor position on the target screen
SInt32 x, y;
newScreen->getJumpCursorPos(x, y);
-
+
switchScreen(newScreen, x, y, false);
}
@@ -884,14 +893,14 @@ Server::isSwitchOkay(BaseClientProxy* newScreen,
if (!preventSwitch && (
(this->m_switchNeedsShift && ((mods & KeyModifierShift) != KeyModifierShift)) ||
- (this->m_switchNeedsControl && ((mods & KeyModifierControl) != KeyModifierControl)) ||
+ (this->m_switchNeedsControl && ((mods & KeyModifierControl) != KeyModifierControl)) ||
(this->m_switchNeedsAlt && ((mods & KeyModifierAlt) != KeyModifierAlt))
)) {
LOG((CLOG_DEBUG1 "need modifiers to switch"));
preventSwitch = true;
stopSwitch();
- }
-
+ }
+
return !preventSwitch;
}
@@ -1171,7 +1180,7 @@ Server::processOptions()
}
else if (id == kOptionClipboardSharing) {
m_enableClipboard = (value != 0);
-
+
if (m_enableClipboard == false) {
LOG((CLOG_NOTE "clipboard sharing is disabled"));
}
@@ -1378,10 +1387,7 @@ Server::handleClientDisconnected(const Event&, void* vclient)
removeActiveClient(client);
removeOldClient(client);
- PacketStreamFilter* streamFileter = dynamic_cast(client->getStream());
- TCPSocket* socket = dynamic_cast(streamFileter->getStream());
delete client;
- m_clientListener->deleteSocket(socket);
}
void
@@ -1391,16 +1397,14 @@ Server::handleClientCloseTimeout(const Event&, void* vclient)
BaseClientProxy* client = static_cast(vclient);
LOG((CLOG_NOTE "forced disconnection of client \"%s\"", getName(client).c_str()));
removeOldClient(client);
- PacketStreamFilter* streamFileter = dynamic_cast(client->getStream());
- TCPSocket* socket = dynamic_cast(streamFileter->getStream());
+
delete client;
- m_clientListener->deleteSocket(socket);
}
void
Server::handleSwitchToScreenEvent(const Event& event, void*)
{
- SwitchToScreenInfo* info =
+ SwitchToScreenInfo* info =
static_cast(event.getData());
ClientList::const_iterator index = m_clients.find(info->m_screen);
@@ -1415,7 +1419,7 @@ Server::handleSwitchToScreenEvent(const Event& event, void*)
void
Server::handleSwitchInDirectionEvent(const Event& event, void*)
{
- SwitchInDirectionInfo* info =
+ SwitchInDirectionInfo* info =
static_cast(event.getData());
// jump to screen in chosen direction from center of this screen
@@ -1705,8 +1709,8 @@ Server::onMouseUp(ButtonID id)
m_ignoreFileTransfer = false;
return;
}
-
- if (m_enableDragDrop) {
+
+ if (m_args.m_enableDragDrop) {
if (!m_screen->isOnScreen()) {
String& file = m_screen->getDraggingFilename();
if (!file.empty()) {
@@ -1791,7 +1795,7 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
// should we switch or not?
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
- if (m_enableDragDrop
+ if (m_args.m_enableDragDrop
&& m_screen->isDraggingStarted()
&& m_active != newScreen
&& m_waitDragInfoThread) {
@@ -1810,7 +1814,7 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
m_waitDragInfoThread = true;
return true;
}
-
+
return false;
}
@@ -1826,7 +1830,7 @@ Server::sendDragInfoThread(void* arg)
di.setFilename(dragFileList);
m_dragFileList.push_back(di);
}
-
+
#if defined(__APPLE__)
// on mac it seems that after faking a LMB up, system would signal back
// to synergy a mouse up event, which doesn't happen on windows. as a
@@ -1849,7 +1853,7 @@ Server::sendDragInfo(BaseClientProxy* newScreen)
{
String infoString;
UInt32 fileCount = DragInformation::setupDragInfo(m_dragFileList, infoString);
-
+
if (fileCount > 0) {
char* info = NULL;
size_t size = infoString.size();
@@ -2059,7 +2063,7 @@ Server::onFileChunkSending(const void* data)
assert(m_active != NULL);
// relay
- m_active->fileChunkSending(chunk->m_chunk[0], &chunk->m_chunk[1], chunk->m_dataSize);
+ m_active->fileChunkSending(chunk->m_chunk[0], &chunk->m_chunk[1], chunk->m_dataSize);
}
void
@@ -2368,7 +2372,7 @@ Server::sendFileToClient(const char* filename)
if (m_sendFileThread != NULL) {
StreamChunker::interruptFile();
}
-
+
m_sendFileThread = new Thread(
new TMethodJob(
this, &Server::sendFileThread,
@@ -2393,7 +2397,7 @@ Server::sendFileThread(void* data)
void
Server::dragInfoReceived(UInt32 fileNum, String content)
{
- if (!m_enableDragDrop) {
+ if (!m_args.m_enableDragDrop) {
LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info."));
return;
}
diff --git a/src/lib/server/Server.h b/src/lib/server/Server.h
index 7681487a..d1e48bd5 100644
--- a/src/lib/server/Server.h
+++ b/src/lib/server/Server.h
@@ -25,6 +25,7 @@
#include "synergy/mouse_types.h"
#include "synergy/INode.h"
#include "synergy/DragInformation.h"
+#include "synergy/ServerArgs.h"
#include "base/Event.h"
#include "base/Stopwatch.h"
#include "base/EventTypes.h"
@@ -106,7 +107,7 @@ public:
ownership of \p primaryClient.
*/
Server(Config& config, PrimaryClient* primaryClient,
- synergy::Screen* screen, IEventQueue* events, bool enableDragDrop);
+ synergy::Screen* screen, IEventQueue* events, ServerArgs const& args);
~Server();
#ifdef TEST_ENV
@@ -472,11 +473,11 @@ private:
Thread* m_writeToDropDirThread;
String m_dragFileExt;
bool m_ignoreFileTransfer;
- bool m_enableDragDrop;
bool m_enableClipboard;
Thread* m_sendDragInfoThread;
bool m_waitDragInfoThread;
ClientListener* m_clientListener;
+ ServerArgs m_args;
};
diff --git a/src/lib/shared/CMakeLists.txt b/src/lib/shared/CMakeLists.txt
new file mode 100644
index 00000000..891f4aa7
--- /dev/null
+++ b/src/lib/shared/CMakeLists.txt
@@ -0,0 +1,32 @@
+# synergy -- mouse and keyboard sharing utility
+# Copyright (C) 2016 Symless 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 LICENSE 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 .
+
+file(GLOB headers "*.h")
+file(GLOB sources "*.cpp")
+
+if (SYNERGY_ADD_HEADERS)
+ list(APPEND sources ${headers})
+endif()
+
+add_library(shared STATIC ${sources})
+
+include_directories(
+ ../
+ ../../../ext
+ ../../../ext/gtest-1.6.0/include
+)
+
+target_link_libraries(shared arch base)
+
diff --git a/src/gui/src/EditionType.h b/src/lib/shared/EditionType.h
similarity index 90%
rename from src/gui/src/EditionType.h
rename to src/lib/shared/EditionType.h
index 5869a32b..66f30aa9 100644
--- a/src/gui/src/EditionType.h
+++ b/src/lib/shared/EditionType.h
@@ -20,11 +20,11 @@
/* Do not reorder these! */
-enum EditionType {
- Basic,
- Pro,
- Trial,
- Unregistered
+enum Edition {
+ kBasic,
+ kPro,
+ Trial_DO_NOT_USE_OR_THERE_WILL_BE_PAIN,
+ kUnregistered
};
#endif // EDITIONTYPE_H
diff --git a/src/lib/shared/SerialKey.cpp b/src/lib/shared/SerialKey.cpp
new file mode 100644
index 00000000..60a039cb
--- /dev/null
+++ b/src/lib/shared/SerialKey.cpp
@@ -0,0 +1,264 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2016 Symless 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 LICENSE 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 .
+ */
+
+#include "SerialKey.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+SerialKey::SerialKey(Edition edition):
+ m_userLimit(1),
+ m_warnTime(ULLONG_MAX),
+ m_expireTime(ULLONG_MAX),
+ m_edition(edition),
+ m_trial(false)
+{
+}
+
+SerialKey::SerialKey(std::string serial) :
+ m_userLimit(1),
+ m_warnTime(0),
+ m_expireTime(0),
+ m_edition(kBasic),
+ m_trial(true)
+{
+ string plainText = decode(serial);
+ bool valid = false;
+ if (!plainText.empty()) {
+ valid = parse(plainText);
+ }
+ if (!valid) {
+ throw std::runtime_error ("Invalid serial key");
+ }
+}
+
+bool
+SerialKey::isExpiring(time_t currentTime) const
+{
+ bool result = false;
+
+ if (m_trial) {
+ if (m_warnTime <= currentTime && currentTime < m_expireTime) {
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+bool
+SerialKey::isExpired(time_t currentTime) const
+{
+ bool result = false;
+
+ if (m_trial) {
+ if (m_expireTime <= currentTime) {
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+bool
+SerialKey::isTrial() const
+{
+ return m_trial;
+}
+
+Edition
+SerialKey::edition() const
+{
+ return m_edition;
+}
+
+std::string
+SerialKey::editionString() const
+{
+ switch (edition()) {
+ case kBasic:
+ return "basic";
+ case kPro:
+ return "pro";
+ default: {
+ std::ostringstream oss;
+ oss << static_cast(edition());
+ return oss.str();
+ }
+ }
+}
+
+static std::string
+hexEncode (std::string const& str) {
+ std::ostringstream oss;
+ for (size_t i = 0; i < str.size(); ++i) {
+ int c = str[i];
+ oss << std::setfill('0') << std::hex << std::setw(2)
+ << std::uppercase;
+ oss << c;
+ }
+ return oss.str();
+}
+
+std::string
+SerialKey::toString() const
+{
+ std::ostringstream oss;
+ oss << "{";
+ if (isTrial()) {
+ oss << "v2;trial;";
+ } else {
+ oss << "v1;";
+ }
+ oss << editionString() << ";";
+ oss << m_name << ";";
+ oss << m_userLimit << ";";
+ oss << m_email << ";";
+ oss << m_company << ";";
+ oss << (isTrial() ? m_warnTime : 0) << ";";
+ oss << (isTrial() ? m_expireTime : 0);
+ oss << "}";
+ return hexEncode(oss.str());
+}
+
+time_t
+SerialKey::daysLeft(time_t currentTime) const
+{
+ unsigned long long timeLeft = 0;
+ unsigned long long const day = 60 * 60 * 24;
+
+ if (currentTime < m_expireTime) {
+ timeLeft = m_expireTime - currentTime;
+ }
+
+ unsigned long long daysLeft = 0;
+ daysLeft = timeLeft % day != 0 ? 1 : 0;
+
+ return timeLeft / day + daysLeft;
+}
+
+std::string
+SerialKey::email() const
+{
+ return m_email;
+}
+
+std::string
+SerialKey::decode(const std::string& serial)
+{
+ static const char* const lut = "0123456789ABCDEF";
+ string output;
+ size_t len = serial.length();
+ if (len & 1) {
+ return output;
+ }
+
+ output.reserve(len / 2);
+ for (size_t i = 0; i < len; i += 2) {
+
+ char a = serial[i];
+ char b = serial[i + 1];
+
+ const char* p = std::lower_bound(lut, lut + 16, a);
+ const char* q = std::lower_bound(lut, lut + 16, b);
+
+ if (*q != b || *p != a) {
+ return output;
+ }
+
+ output.push_back(static_cast(((p - lut) << 4) | (q - lut)));
+ }
+
+ return output;
+}
+
+bool
+SerialKey::parse(std::string plainSerial)
+{
+ string parityStart = plainSerial.substr(0, 1);
+ string parityEnd = plainSerial.substr(plainSerial.length() - 1, 1);
+
+ bool valid = false;
+
+ // check for parity chars { and }, record parity result, then remove them.
+ if (parityStart == "{" && parityEnd == "}") {
+ plainSerial = plainSerial.substr(1, plainSerial.length() - 2);
+
+ // tokenize serialised subscription.
+ vector parts;
+ std::string::size_type pos = 0;
+ bool look = true;
+ while (look) {
+ std::string::size_type start = pos;
+ pos = plainSerial.find(";", pos);
+ if (pos == string::npos) {
+ pos = plainSerial.length();
+ look = false;
+ }
+ parts.push_back(plainSerial.substr(start, pos - start));
+ pos += 1;
+ }
+
+ if ((parts.size() == 8)
+ && (parts.at(0).find("v1") != string::npos)) {
+ // e.g.: {v1;basic;Bob;1;email;company name;1398297600;1398384000}
+ m_edition = parseEdition(parts.at(1));
+ m_name = parts.at(2);
+ m_trial = false;
+ sscanf(parts.at(3).c_str(), "%d", &m_userLimit);
+ m_email = parts.at(4);
+ m_company = parts.at(5);
+ sscanf(parts.at(6).c_str(), "%lld", &m_warnTime);
+ sscanf(parts.at(7).c_str(), "%lld", &m_expireTime);
+ valid = true;
+ }
+ else if ((parts.size() == 9)
+ && (parts.at(0).find("v2") != string::npos)) {
+ // e.g.: {v2;trial;basic;Bob;1;email;company name;1398297600;1398384000}
+ m_trial = parts.at(1) == "trial" ? true : false;
+ m_edition = parseEdition(parts.at(2));
+ m_name = parts.at(3);
+ sscanf(parts.at(4).c_str(), "%d", &m_userLimit);
+ m_email = parts.at(5);
+ m_company = parts.at(6);
+ sscanf(parts.at(7).c_str(), "%lld", &m_warnTime);
+ sscanf(parts.at(8).c_str(), "%lld", &m_expireTime);
+ valid = true;
+ }
+ }
+
+ return valid;
+}
+
+Edition
+SerialKey::parseEdition(std::string const& editionStr)
+{
+ Edition e = kBasic;
+ if (editionStr == "pro") {
+ e = kPro;
+ }
+
+ return e;
+}
diff --git a/src/lib/shared/SerialKey.h b/src/lib/shared/SerialKey.h
new file mode 100644
index 00000000..dd9b7160
--- /dev/null
+++ b/src/lib/shared/SerialKey.h
@@ -0,0 +1,84 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2016 Symless 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 LICENSE 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 .
+ */
+
+#pragma once
+
+#include
+#include
+#include "EditionType.h"
+
+#ifdef TEST_ENV
+#include "gtest/gtest_prod.h"
+#endif
+
+class SerialKey {
+ friend bool operator== (SerialKey const&, SerialKey const&);
+public:
+ explicit SerialKey(Edition edition = kUnregistered);
+ explicit SerialKey(std::string serial);
+
+ bool isExpiring(time_t currentTime) const;
+ bool isExpired(time_t currentTime) const;
+ bool isTrial() const;
+ time_t daysLeft(time_t currentTime) const;
+ std::string email() const;
+ Edition edition() const;
+ std::string toString() const;
+
+ static std::string decode(const std::string& serial);
+ static Edition parseEdition(const std::string& editionStr);
+
+private:
+ bool parse(std::string plainSerial);
+ std::string editionString() const;
+
+#ifdef TEST_ENV
+private:
+ FRIEND_TEST(SerialKeyTests, parse_noParty_invalid);
+ FRIEND_TEST(SerialKeyTests, parse_invalidPartsLenghth_invalid);
+ FRIEND_TEST(SerialKeyTests, parse_validV1Serial_valid);
+ FRIEND_TEST(SerialKeyTests, parse_validV2Serial_valid);
+#endif
+
+private:
+ std::string m_name;
+ std::string m_email;
+ std::string m_company;
+ unsigned m_userLimit;
+ unsigned long long m_warnTime;
+ unsigned long long m_expireTime;
+ Edition m_edition;
+ bool m_trial;
+};
+
+
+inline bool
+operator== (SerialKey const& lhs, SerialKey const& rhs) {
+ return (lhs.m_name == rhs.m_name) &&
+ (lhs.m_email == rhs.m_email) &&
+ (lhs.m_company == rhs.m_company) &&
+ (lhs.m_userLimit == rhs.m_userLimit) &&
+ (lhs.m_warnTime == rhs.m_warnTime) &&
+ (lhs.m_expireTime == rhs.m_expireTime) &&
+ (lhs.m_edition == rhs.m_edition) &&
+ (lhs.m_trial == rhs.m_trial);
+}
+
+inline bool
+operator!= (SerialKey const& lhs, SerialKey const& rhs) {
+ return !(lhs == rhs);
+}
diff --git a/src/lib/synergy/ArgParser.cpp b/src/lib/synergy/ArgParser.cpp
index 431a91b7..6693ebf0 100644
--- a/src/lib/synergy/ArgParser.cpp
+++ b/src/lib/synergy/ArgParser.cpp
@@ -1,11 +1,11 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless 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 LICENSE 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
@@ -70,6 +70,9 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv)
else if (isArg(i, argc, argv, "", "--prm-hc", 1)) {
DpiHelper::s_primaryHeightCenter = synergy::string::stringToSizeType(argv[++i]);
}
+ else if (isArg(i, argc, argv, "", "--serial-key", 1)) {
+ args.m_serial = SerialKey(argv[++i]);
+ }
else {
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
return false;
@@ -107,7 +110,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
// ignore -- included for backwards compatibility
}
else if (isArg(i, argc, argv, NULL, "--yscroll", 1)) {
- // define scroll
+ // define scroll
args.m_yscroll = atoi(argv[++i]);
}
else {
@@ -189,18 +192,10 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
args.m_loginAuthenticate = true;
return true;
}
- else if (isArg(i, argc, argv, NULL, "--get-plugin-list", 0)) {
- args.m_getPluginList = true;
- return true;
- }
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
args.m_getInstalledDir = true;
return true;
}
- else if (isArg(i, argc, argv, NULL, "--get-plugin-dir", 0)) {
- args.m_getPluginDir = true;
- return true;
- }
else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) {
args.m_getProfileDir = true;
return true;
@@ -209,26 +204,14 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
args.m_getArch = true;
return true;
}
- else if (isArg(i, argc, argv, NULL, "--subscription-serial", 1)) {
- args.m_subscriptionSerial = argv[++i];
- if (args.m_subscriptionSerial.empty()) {
- LOG((CLOG_CRIT "subscription error: serial was not provided"));
- return false;
- }
- return true;
- }
- else if (isArg(i, argc, argv, NULL, "--get-subscription-filename", 0)) {
- args.m_getSubscriptionFilename = true;
- return true;
- }
- else if (isArg(i, argc, argv, NULL, "--check-subscription", 0)) {
- args.m_checkSubscription = true;
- return true;
- }
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
args.m_notifyActivation = true;
return true;
}
+ else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) {
+ args.m_notifyUpdate = true;
+ return true;
+ }
else {
return false;
}
@@ -292,10 +275,10 @@ ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
argsBase().m_enableIpc = true;
}
else if (isArg(i, argc, argv, NULL, "--server")) {
- // HACK: stop error happening when using portable (synergyp)
+ // HACK: stop error happening when using portable (synergyp)
}
else if (isArg(i, argc, argv, NULL, "--client")) {
- // HACK: stop error happening when using portable (synergyp)
+ // HACK: stop error happening when using portable (synergyp)
}
else if (isArg(i, argc, argv, NULL, "--enable-drag-drop")) {
bool useDragDrop = true;
@@ -399,7 +382,7 @@ ArgParser::splitCommandString(String& command, std::vector& argv)
else if (space > rightDoubleQuote){
searchDoubleQuotes(command, leftDoubleQuote, rightDoubleQuote, rightDoubleQuote + 1);
}
-
+
if (!ignoreThisSpace) {
String subString = command.substr(startPos, space - startPos);
@@ -465,7 +448,7 @@ ArgParser::getArgv(std::vector& argsArray)
// them to the inner array. So caller only need to use
// delete[] to delete the outer array
const char** argv = new const char*[argc];
-
+
for (size_t i = 0; i < argc; i++) {
argv[i] = argsArray[i].c_str();
}
@@ -497,7 +480,7 @@ ArgParser::assembleCommand(std::vector& argsArray, String ignoreArg, in
if (!result.empty()) {
// remove the tail space
- result = result.substr(0, result.size() - 1);
+ result = result.substr(0, result.size() - 1);
}
return result;
@@ -514,13 +497,13 @@ bool
ArgParser::checkUnexpectedArgs()
{
#if SYSAPI_WIN32
- // suggest that user installs as a windows service. when launched as
+ // suggest that user installs as a windows service. when launched as
// service, process should automatically detect that it should run in
// daemon mode.
if (argsBase().m_daemon) {
- LOG((CLOG_ERR
+ LOG((CLOG_ERR
"the --daemon argument is not supported on windows. "
- "instead, install %s as a service (--service install)",
+ "instead, install %s as a service (--service install)",
argsBase().m_pname));
return true;
}
diff --git a/src/lib/synergy/ServerApp.cpp b/src/lib/synergy/ServerApp.cpp
index 23884aec..ae1a2077 100644
--- a/src/lib/synergy/ServerApp.cpp
+++ b/src/lib/synergy/ServerApp.cpp
@@ -647,7 +647,7 @@ ServerApp::openClientListener(const NetworkAddress& address)
Server*
ServerApp::openServer(Config& config, PrimaryClient* primaryClient)
{
- Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args().m_enableDragDrop);
+ Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args());
try {
m_events->adoptHandler(
m_events->forServer().disconnected(), server,
diff --git a/src/lib/synergy/ServerArgs.cpp b/src/lib/synergy/ServerArgs.cpp
index f56f6e8d..52166f2a 100644
--- a/src/lib/synergy/ServerArgs.cpp
+++ b/src/lib/synergy/ServerArgs.cpp
@@ -19,6 +19,7 @@
ServerArgs::ServerArgs() :
m_configFile(),
+ m_serial(),
m_config(NULL)
{
}
diff --git a/src/lib/synergy/ServerArgs.h b/src/lib/synergy/ServerArgs.h
index 54310f8e..e139d110 100644
--- a/src/lib/synergy/ServerArgs.h
+++ b/src/lib/synergy/ServerArgs.h
@@ -1,11 +1,11 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless 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 LICENSE 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
@@ -18,6 +18,7 @@
#pragma once
#include "synergy/ArgsBase.h"
+#include "shared/SerialKey.h"
class NetworkAddress;
class Config;
@@ -28,5 +29,6 @@ public:
public:
String m_configFile;
+ SerialKey m_serial;
Config* m_config;
};
diff --git a/src/lib/synergy/SubscriptionKey.h b/src/lib/synergy/SubscriptionKey.h
deleted file mode 100644
index 28744fed..00000000
--- a/src/lib/synergy/SubscriptionKey.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * synergy -- mouse and keyboard sharing utility
- * Copyright (C) 2015 Synergy Seamless Inc.
- *
- * 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 LICENSE 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 .
- */
-
-#pragma once
-
-#include "base/String.h"
-
-struct SubscriptionKey {
- String m_name;
- String m_type;
- String m_email;
- String m_company;
- int m_userLimit;
- int m_warnTime;
- int m_expireTime;
-};
diff --git a/src/lib/synergy/SubscriptionManager.cpp b/src/lib/synergy/SubscriptionManager.cpp
deleted file mode 100644
index 78207dc2..00000000
--- a/src/lib/synergy/SubscriptionManager.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * synergy -- mouse and keyboard sharing utility
- * Copyright (C) 2015 Synergy Seamless Inc.
- *
- * 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 LICENSE 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 .
- */
-
-#include "synergy/SubscriptionManager.h"
-
-#include "synergy/XSynergy.h"
-#include "arch/Arch.h"
-#include "base/Log.h"
-#include "base/String.h"
-#include "common/Version.h"
-
-#include
-#include
-#include
-#include
-#include
-//#include
-
-#if SYSAPI_WIN32
-const char* kFile = "Synergy.subkey";
-#else
-const char* kFile = ".synergy.subkey";
-#endif
-
-//
-// SubscriptionManager
-//
-
-SubscriptionManager::SubscriptionManager() :
- m_key()
-{
-}
-
-void
-SubscriptionManager::checkFile(const String& filename_)
-{
- String filename = filename_;
- if (filename.empty()) {
- filename = getFilename();
- }
-
- std::ifstream stream(filename.c_str());
- if (!stream.is_open()) {
- throw XSubscription(synergy::string::sprintf(
- "Could not open, path=%s", filename.c_str()));
- }
-
- String serial;
- stream >> serial;
-
- String plainText = decode(serial);
- parsePlainSerial(plainText, m_key);
-
- LOG((CLOG_DEBUG "subscription is valid"));
-}
-
-void
-SubscriptionManager::activate(const String& serial)
-{
- String plainText = decode(serial);
- parsePlainSerial(plainText, m_key);
-
- String filename = getFilename();
- std::ofstream stream(filename.c_str());
- if (!stream.is_open()) {
- throw XSubscription(synergy::string::sprintf(
- "Could not open, file=%s", filename.c_str()));
- }
-
- stream << serial << std::endl;
- LOG((CLOG_DEBUG "subscription file created, path=%s", filename.c_str()));
-}
-
-String
-SubscriptionManager::decode(const String& input)
-{
- static const char* const lut = "0123456789ABCDEF";
- size_t len = input.length();
- if (len & 1) {
- throw XSubscription("Invalid serial, wrong length.");
- }
-
- String output;
- output.reserve(len / 2);
- for (size_t i = 0; i < len; i += 2) {
-
- char a = input[i];
- char b = input[i + 1];
-
- const char* p = std::lower_bound(lut, lut + 16, a);
- const char* q = std::lower_bound(lut, lut + 16, b);
-
- if (*q != b || *p != a) {
- throw XSubscription("Invalid serial, unrecognized digit.");
- }
-
- output.push_back(static_cast(((p - lut) << 4) | (q - lut)));
- }
-
- return output;
-}
-
-void
-SubscriptionManager::parsePlainSerial(const String& plainText, SubscriptionKey& key)
-{
- String serial;
- String parityStart = plainText.substr(0, 1);
- String parityEnd = plainText.substr(plainText.length() - 1, 1);
-
- // check for parity chars { and }, record parity result, then remove them.
- if (parityStart == "{" && parityEnd == "}") {
- serial = plainText.substr(1, plainText.length() - 2);
-
- // tokenize serialised subscription.
- std::vector parts;
- std::string::size_type pos = 0;
- bool look = true;
- while (look) {
- std::string::size_type start = pos;
- pos = serial.find(";", pos);
- if (pos == String::npos) {
- pos = plainText.length();
- look = false;
- }
- parts.push_back(serial.substr(start, pos - start));
- pos += 1;
- }
-
- // e.g.: {v1;trial;Bob;1;email;company name;1398297600;1398384000}
- if ((parts.size() == 8)
- && (parts.at(0).find("v1") != String::npos)) {
- key.m_type = parts.at(1);
- key.m_name = parts.at(2);
- sscanf(parts.at(3).c_str(), "%d", &key.m_userLimit);
- key.m_email = parts.at(4);
- key.m_company = parts.at(5);
- sscanf(parts.at(6).c_str(), "%d", &key.m_warnTime);
- sscanf(parts.at(7).c_str(), "%d", &key.m_expireTime);
-
- // only limit to trial version
- if (key.m_type == "trial") {
- if (time(0) > key.m_expireTime) {
- throw XSubscription("trial has expired");
- }
- else if (time(0) > key.m_warnTime) {
- int secLeft = key.m_expireTime - static_cast(time(0));
- const int spd = 60 * 60 * 24;
- int dayLeft = secLeft / spd + 1;
- LOG((CLOG_NOTE "trial will end in %d %s",
- dayLeft,
- dayLeft == 1 ? "day" : "days"));
- }
- }
-
- const char* userText = (key.m_userLimit == 1) ? "user" : "users";
- LOG((CLOG_INFO "%s subscription valid is for %d %s, registered to %s",
- key.m_type.c_str(),
- key.m_userLimit,
- userText,
- key.m_name.c_str()));
-
- return;
- }
- }
-
- throw XSubscription(synergy::string::sprintf("Serial is invalid."));
-}
-
-String
-SubscriptionManager::getFilename()
-{
- String path = ARCH->getProfileDirectory();
- path = ARCH->concatPath(path, kFile);
- if (path.empty()) {
- throw XSubscription("Could not get filename.");
- }
-
- return path;
-}
-
-void
-SubscriptionManager::printFilename()
-{
- std::cout << getFilename() << std::endl;
-}
diff --git a/src/lib/synergy/SubscriptionManager.h b/src/lib/synergy/SubscriptionManager.h
deleted file mode 100644
index fb52701b..00000000
--- a/src/lib/synergy/SubscriptionManager.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * synergy -- mouse and keyboard sharing utility
- * Copyright (C) 2015 Synergy Seamless Inc.
- *
- * 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 LICENSE 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 .
- */
-
-#pragma once
-
-#include "SubscriptionKey.h"
-#include "common/common.h"
-
-#include "gtest/gtest_prod.h"
-
-class SubscriptionManager {
-public:
- SubscriptionManager();
-
- //! Check the subscription activation file
- void checkFile(const String& filename);
-
- //! Create a subscription activation file based on a serial
- void activate(const String& serial);
-
- //! Use standard output to return subscription filename to gui
- void printFilename();
-
-private:
- FRIEND_TEST(SubscriptionTests, decode_invalidLength_throwException);
- FRIEND_TEST(SubscriptionTests, decode_invalidSerial_outputPlainText);
- FRIEND_TEST(SubscriptionTests, decode_unrecognizedDigit_throwException);
- FRIEND_TEST(SubscriptionTests, parsePlainSerial_noParity_throwException);
- FRIEND_TEST(SubscriptionTests, parsePlainSerial_invalidSerial_throwException);
- FRIEND_TEST(SubscriptionTests, parsePlainSerial_validSerial_validSubscriptionKey);
- FRIEND_TEST(SubscriptionTests, parsePlainSerial_expiredTrialSerial_throwException);
- FRIEND_TEST(SubscriptionTests, parsePlainSerial_expiredBasicSerial_validSubscriptionKey);
- FRIEND_TEST(SubscriptionTests, parsePlainSerial_validSerialWithoutCompany_validSubscriptionKey);
-
-private:
- String decode(const String& input);
- void parsePlainSerial(const String& plainText, SubscriptionKey& key);
- String getFilename();
-
- SubscriptionKey m_key;
-};
diff --git a/src/lib/synergy/ToolApp.cpp b/src/lib/synergy/ToolApp.cpp
index e6695f51..3dcfd05d 100644
--- a/src/lib/synergy/ToolApp.cpp
+++ b/src/lib/synergy/ToolApp.cpp
@@ -1,11 +1,11 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless 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 LICENSE 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
@@ -18,7 +18,6 @@
#include "synergy/ToolApp.h"
#include "synergy/ArgParser.h"
-#include "synergy/SubscriptionManager.h"
#include "arch/Arch.h"
#include "base/Log.h"
#include "base/String.h"
@@ -72,50 +71,17 @@ ToolApp::run(int argc, char** argv)
else if (m_args.m_loginAuthenticate) {
loginAuth();
}
- else if (m_args.m_getPluginList) {
- getPluginList();
- }
else if (m_args.m_getInstalledDir) {
std::cout << ARCH->getInstalledDirectory() << std::endl;
}
- else if (m_args.m_getPluginDir) {
- std::cout << ARCH->getPluginDirectory() << std::endl;
- }
else if (m_args.m_getProfileDir) {
std::cout << ARCH->getProfileDirectory() << std::endl;
}
else if (m_args.m_getArch) {
std::cout << ARCH->getPlatformName() << std::endl;
}
- else if (!m_args.m_subscriptionSerial.empty()) {
- try {
- SubscriptionManager subscriptionManager;
- subscriptionManager.activate(m_args.m_subscriptionSerial);
- }
- catch (XSubscription& e) {
- LOG((CLOG_CRIT "subscription error: %s", e.what()));
- return kExitSubscription;
- }
- }
- else if (m_args.m_getSubscriptionFilename) {
- try {
- SubscriptionManager subscriptionManager;
- subscriptionManager.printFilename();
- }
- catch (XSubscription& e) {
- LOG((CLOG_CRIT "subscription error: %s", e.what()));
- return kExitSubscription;
- }
- }
- else if (m_args.m_checkSubscription) {
- try {
- SubscriptionManager subscriptionManager;
- subscriptionManager.checkFile("");
- }
- catch (XSubscription& e) {
- LOG((CLOG_CRIT "subscription error: %s", e.what()));
- return kExitSubscription;
- }
+ else if (m_args.m_notifyUpdate) {
+ notifyUpdate();
}
else if (m_args.m_notifyActivation) {
notifyActivation();
@@ -172,11 +138,29 @@ ToolApp::loginAuth()
}
void
-ToolApp::getPluginList()
+ToolApp::notifyUpdate()
{
+ String data;
+ std::cin >> data;
+
+ std::vector parts = synergy::string::splitString(data, ':');
+ size_t count = parts.size();
+
+ if (count == 3) {
+ std::stringstream ss;
+ ss << JSON_URL << "notify/update";
+ ss << "?from=" << parts[0];
+ ss << "&to=" << parts[1];
+ ss << "&serial=" << parts[2];
+
+ std::cout << ARCH->internet().get(ss.str()) << std::endl;
+ }
+ else {
+ throw XSynergy("Invalid update data.");
+ }
}
-void
+void
ToolApp::notifyActivation()
{
String info;
diff --git a/src/lib/synergy/ToolApp.h b/src/lib/synergy/ToolApp.h
index 8706c79a..771b298f 100644
--- a/src/lib/synergy/ToolApp.h
+++ b/src/lib/synergy/ToolApp.h
@@ -29,8 +29,8 @@ public:
private:
void loginAuth();
- void getPluginList();
void notifyActivation();
+ void notifyUpdate();
private:
ToolArgs m_args;
diff --git a/src/lib/synergy/ToolArgs.cpp b/src/lib/synergy/ToolArgs.cpp
index f5d2524a..2685c1df 100644
--- a/src/lib/synergy/ToolArgs.cpp
+++ b/src/lib/synergy/ToolArgs.cpp
@@ -20,14 +20,10 @@
ToolArgs::ToolArgs() :
m_printActiveDesktopName(false),
m_loginAuthenticate(false),
- m_getPluginList(false),
- m_getPluginDir(false),
m_getInstalledDir(false),
m_getProfileDir(false),
m_getArch(false),
- m_getSubscriptionFilename(false),
- m_checkSubscription(false),
m_notifyActivation(false),
- m_subscriptionSerial()
+ m_notifyUpdate(false)
{
}
diff --git a/src/lib/synergy/ToolArgs.h b/src/lib/synergy/ToolArgs.h
index 0ebc0a4a..4619efc1 100644
--- a/src/lib/synergy/ToolArgs.h
+++ b/src/lib/synergy/ToolArgs.h
@@ -26,13 +26,9 @@ public:
public:
bool m_printActiveDesktopName;
bool m_loginAuthenticate;
- bool m_getPluginList;
- bool m_getPluginDir;
bool m_getInstalledDir;
bool m_getProfileDir;
bool m_getArch;
- bool m_getSubscriptionFilename;
- bool m_checkSubscription;
bool m_notifyActivation;
- String m_subscriptionSerial;
+ bool m_notifyUpdate;
};
diff --git a/src/test/integtests/net/NetworkTests.cpp b/src/test/integtests/net/NetworkTests.cpp
index 79ef7c99..dbb3dd1e 100644
--- a/src/test/integtests/net/NetworkTests.cpp
+++ b/src/test/integtests/net/NetworkTests.cpp
@@ -129,7 +129,9 @@ TEST_F(NetworkTests, sendToClient_mockData)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
- Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
+ ServerArgs serverArgs;
+ serverArgs.m_enableDragDrop = true;
+ Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
server.m_mock = true;
listener.setServer(&server);
@@ -142,10 +144,10 @@ TEST_F(NetworkTests, sendToClient_mockData)
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
- ClientArgs args;
- args.m_enableDragDrop = true;
- args.m_enableCrypto = false;
- Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
+ ClientArgs clientArgs;
+ clientArgs.m_enableDragDrop = true;
+ clientArgs.m_enableCrypto = false;
+ Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
m_events.adoptHandler(
m_events.forFile().fileRecieveCompleted(), &client,
@@ -185,7 +187,9 @@ TEST_F(NetworkTests, sendToClient_mockFile)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
- Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
+ ServerArgs serverArgs;
+ serverArgs.m_enableDragDrop = true;
+ Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
server.m_mock = true;
listener.setServer(&server);
@@ -198,10 +202,10 @@ TEST_F(NetworkTests, sendToClient_mockFile)
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
- ClientArgs args;
- args.m_enableDragDrop = true;
- args.m_enableCrypto = false;
- Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
+ ClientArgs clientArgs;
+ clientArgs.m_enableDragDrop = true;
+ clientArgs.m_enableCrypto = false;
+ Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
m_events.adoptHandler(
m_events.forFile().fileRecieveCompleted(), &client,
@@ -235,7 +239,9 @@ TEST_F(NetworkTests, sendToServer_mockData)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
- Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
+ ServerArgs serverArgs;
+ serverArgs.m_enableDragDrop = true;
+ Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
server.m_mock = true;
listener.setServer(&server);
@@ -247,10 +253,10 @@ TEST_F(NetworkTests, sendToServer_mockData)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
- ClientArgs args;
- args.m_enableDragDrop = true;
- args.m_enableCrypto = false;
- Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
+ ClientArgs clientArgs;
+ clientArgs.m_enableDragDrop = true;
+ clientArgs.m_enableCrypto = false;
+ Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
m_events.adoptHandler(
m_events.forClientListener().connected(), &listener,
@@ -290,7 +296,9 @@ TEST_F(NetworkTests, sendToServer_mockFile)
ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true));
ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter));
- Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true);
+ ServerArgs serverArgs;
+ serverArgs.m_enableDragDrop = true;
+ Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs);
server.m_mock = true;
listener.setServer(&server);
@@ -302,10 +310,10 @@ TEST_F(NetworkTests, sendToServer_mockFile)
ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape));
ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos));
- ClientArgs args;
- args.m_enableDragDrop = true;
- args.m_enableCrypto = false;
- Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args);
+ ClientArgs clientArgs;
+ clientArgs.m_enableDragDrop = true;
+ clientArgs.m_enableCrypto = false;
+ Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs);
m_events.adoptHandler(
m_events.forClientListener().connected(), &listener,
diff --git a/src/test/unittests/CMakeLists.txt b/src/test/unittests/CMakeLists.txt
index 4cdab9bf..3e49dc3c 100644
--- a/src/test/unittests/CMakeLists.txt
+++ b/src/test/unittests/CMakeLists.txt
@@ -68,4 +68,4 @@ endif()
add_executable(unittests ${sources})
target_link_libraries(unittests
- arch base client server common io net platform server synergy mt ipc gtest gmock ${libs} ${OPENSSL_LIBS})
+ arch base client server common io net platform server synergy mt ipc gtest gmock shared ${libs} ${OPENSSL_LIBS})
diff --git a/src/test/unittests/shared/SerialKeyTests.cpp b/src/test/unittests/shared/SerialKeyTests.cpp
new file mode 100644
index 00000000..126d26e8
--- /dev/null
+++ b/src/test/unittests/shared/SerialKeyTests.cpp
@@ -0,0 +1,147 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2016 Symless Inc.
+ *
+ * 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 LICENSE 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 .
+ */
+
+#define TEST_ENV
+
+#include "shared/SerialKey.h"
+
+#include "test/global/gtest.h"
+
+TEST(SerialKeyTests, decode_empty_returnEmptyString)
+{
+ std::string plainText = SerialKey::decode("");
+ EXPECT_EQ(0, plainText.size());
+}
+
+TEST(SerialKeyTests, decode_invalidDigit_returnEmptyString)
+{
+ std::string plainText = SerialKey::decode("MOCKZ");
+ EXPECT_EQ(0, plainText.size());
+}
+
+TEST(SerialKeyTests, decode_validSerial_returnPlainText)
+{
+ std::string plainText = SerialKey::decode("53796E6572677920726F636B7321");
+ EXPECT_EQ("Synergy rocks!", plainText);
+}
+
+TEST(SerialKeyTests, parse_noParty_invalid)
+{
+ SerialKey serial;
+ bool r = serial.parse("MOCK");
+ EXPECT_FALSE(r);
+}
+
+TEST(SerialKeyTests, parse_invalidPartsLenghth_invalid)
+{
+ SerialKey serial;
+ bool r = serial.parse("{Synergy;Rocks}");
+ EXPECT_FALSE(r);
+}
+
+TEST(SerialKeyTests, parse_validV1Serial_valid)
+{
+ SerialKey serial;
+ bool r = serial.parse("{v1;basic;Bob;1;email;company name;0;86400}");
+ EXPECT_EQ(true, r);
+ EXPECT_EQ(kBasic, serial.edition());
+ EXPECT_FALSE(serial.isExpired(0));
+ EXPECT_EQ(true, serial.daysLeft(0));
+ EXPECT_FALSE(serial.isExpiring(1));
+}
+
+TEST(SerialKeyTests, parse_validV2Serial_valid)
+{
+ SerialKey serial;
+ bool r = serial.parse("{v2;trial;pro;Bob;1;email;company name;0;86400}");
+ EXPECT_EQ(true, r);
+ EXPECT_EQ(kPro, serial.edition());
+ EXPECT_FALSE(serial.isExpired(0));
+ EXPECT_EQ(true, serial.daysLeft(0));
+ EXPECT_EQ(true, serial.isExpiring(1));
+ EXPECT_EQ(true, serial.isTrial());
+}
+
+TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse)
+{
+ // {v2;trial;basic;Bob;1;email;company name;1;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B313B38363430307D");
+ EXPECT_EQ(true, serial.isTrial());
+ EXPECT_FALSE(serial.isExpiring(0));
+ EXPECT_EQ(kBasic, serial.edition());
+}
+
+TEST(SerialKeyTests, isExpiring_expiringV2TrialBasicSerial_returnTrue)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(true, serial.isTrial());
+ EXPECT_EQ(true, serial.isExpiring(1));
+}
+
+TEST(SerialKeyTests, isExpiring_expiredV2TrialBasicSerial_returnFalse)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(true, serial.isTrial());
+ EXPECT_FALSE(serial.isExpiring(86401));
+}
+
+TEST(SerialKeyTests, isExpired_validV2TrialBasicSerial_returnFalse)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(true, serial.isTrial());
+ EXPECT_FALSE(serial.isExpired(0));
+}
+
+TEST(SerialKeyTests, isExpired_expiringV2TrialBasicSerial_returnFalse)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(true, serial.isTrial());
+ EXPECT_FALSE(serial.isExpired(1));
+}
+
+TEST(SerialKeyTests, isExpired_expiredV2TrialBasicSerial_returnTrue)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(true, serial.isTrial());
+ EXPECT_EQ(true, serial.isExpired(86401));
+}
+
+TEST(SerialKeyTests, daysLeft_validExactlyOneDayV2TrialBasicSerial_returnOne)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(1, serial.daysLeft(0));
+}
+
+TEST(SerialKeyTests, daysLeft_validWithinOneDayV2TrialBasicSerial_returnOne)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(1, serial.daysLeft(1));
+}
+
+TEST(SerialKeyTests, daysLeft_expiredV2TrialBasicSerial_returnZero)
+{
+ // {v2;trial;basic;Bob;1;email;company name;0;86400}
+ SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D");
+ EXPECT_EQ(0, serial.daysLeft(86401));
+}
diff --git a/src/test/unittests/synergy/ServerArgsParsingTests.cpp b/src/test/unittests/synergy/ServerArgsParsingTests.cpp
index 5ae18b94..f931f7e5 100644
--- a/src/test/unittests/synergy/ServerArgsParsingTests.cpp
+++ b/src/test/unittests/synergy/ServerArgsParsingTests.cpp
@@ -1,11 +1,11 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless 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 LICENSE 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
diff --git a/src/test/unittests/synergy/SubscriptionTests.cpp b/src/test/unittests/synergy/SubscriptionTests.cpp
deleted file mode 100644
index eeda3e7b..00000000
--- a/src/test/unittests/synergy/SubscriptionTests.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * synergy -- mouse and keyboard sharing utility
- * Copyright (C) 2015 Synergy Seamless Inc.
- *
- * 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 LICENSE 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 .
- */
-
-#include "synergy/SubscriptionManager.h"
-#include "synergy/XSynergy.h"
-
-#include "test/global/gtest.h"
-
-TEST(SubscriptionTests, decode_invalidLength_throwException)
-{
- SubscriptionManager subscriptionManager;
- String serial("ABC");
-
- EXPECT_THROW(subscriptionManager.decode(serial), XSubscription);
-}
-
-TEST(SubscriptionTests, decode_unrecognizedDigit_throwException)
-{
- SubscriptionManager subscriptionManager;
- String serial("MOCK");
-
- EXPECT_THROW(subscriptionManager.decode(serial), XSubscription);
-}
-
-TEST(SubscriptionTests, parsePlainSerial_noParity_throwException)
-{
- SubscriptionManager subscriptionManager;
- String painText("MOCK");
- SubscriptionKey key;
-
- EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription);
-}
-
-TEST(SubscriptionTests, parsePlainSerial_invalidSerial_throwException)
-{
- SubscriptionManager subscriptionManager;
- String painText("{MOCK}");
- SubscriptionKey key;
-
- EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription);
-}
-
-TEST(SubscriptionTests, parsePlainSerial_validSerial_validSubscriptionKey)
-{
- // valid until 2 March 2049
- SubscriptionManager subscriptionManager;
- String painText("{v1;trial;Bob;1;a@a.a;mock company;2147483647;2147483647}");
- SubscriptionKey key;
- subscriptionManager.parsePlainSerial(painText, key);
-
- EXPECT_EQ("trial", key.m_type);
- EXPECT_EQ("Bob", key.m_name);
- EXPECT_EQ(1, key.m_userLimit);
- EXPECT_EQ("a@a.a", key.m_email);
- EXPECT_EQ("mock company", key.m_company);
- EXPECT_EQ(2147483647, key.m_warnTime);
- EXPECT_EQ(2147483647, key.m_expireTime);
-}
-
-TEST(SubscriptionTests, parsePlainSerial_validSerialWithoutCompany_validSubscriptionKey)
-{
- // valid until 2 March 2049
- SubscriptionManager subscriptionManager;
- String painText("{v1;trial;Bob;1;a@a.a;;2147483647;2147483647}");
- SubscriptionKey key;
- subscriptionManager.parsePlainSerial(painText, key);
-
- EXPECT_EQ("trial", key.m_type);
- EXPECT_EQ("Bob", key.m_name);
- EXPECT_EQ(1, key.m_userLimit);
- EXPECT_EQ("a@a.a", key.m_email);
- EXPECT_EQ("", key.m_company);
- EXPECT_EQ(2147483647, key.m_warnTime);
- EXPECT_EQ(2147483647, key.m_expireTime);
-}
-
-TEST(SubscriptionTests, parsePlainSerial_expiredTrialSerial_throwException)
-{
- SubscriptionManager subscriptionManager;
- String painText("{v1;trial;Bob;1;1398297600;1398384000}");
- SubscriptionKey key;
-
- EXPECT_THROW(subscriptionManager.parsePlainSerial(painText, key), XSubscription);
-}
-
-TEST(SubscriptionTests, parsePlainSerial_expiredBasicSerial_validSubscriptionKey)
-{
- SubscriptionManager subscriptionManager;
- String painText("{v1;basic;Bob;1;a@a.a;mock company;1398297600;1398384000}");
- SubscriptionKey key;
- subscriptionManager.parsePlainSerial(painText, key);
-
- EXPECT_EQ("basic", key.m_type);
- EXPECT_EQ("Bob", key.m_name);
- EXPECT_EQ(1, key.m_userLimit);
- EXPECT_EQ("a@a.a", key.m_email);
- EXPECT_EQ("mock company", key.m_company);
- EXPECT_EQ(1398297600, key.m_warnTime);
- EXPECT_EQ(1398384000, key.m_expireTime);
-}