Merge changes from v1.8.5
This commit is contained in:
commit
96efe5fb73
|
@ -1,8 +1,7 @@
|
|||
### Operating Systems ###
|
||||
|
||||
Client: Applesoft Windy OS 10
|
||||
|
||||
Server: microOS Tiara
|
||||
Client: Applesoft Windy OS 10
|
||||
|
||||
**READ ME, DELETE ME**: On Windows, hold the Windows key and press 'r', type 'winver' and hit return to get your OS version. On Mac, hit the Apple menu (top left of the screen) and check 'About this Mac'. Linux users... you know what you're using ;)
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
config.h
|
||||
.DS_Store
|
||||
*.pyc
|
||||
*.o
|
||||
*~
|
||||
\.*.swp
|
||||
*build-gui-Desktop_Qt*
|
||||
/bin
|
||||
/lib
|
||||
/build
|
||||
|
|
28
ChangeLog
28
ChangeLog
|
@ -1,16 +1,22 @@
|
|||
v1.8.5-stable
|
||||
=============
|
||||
Bug #5680 - Server crashes when disconnecting SSL clients
|
||||
Bug #5626 - Build fails using Xcode 8 and macOS SDK 10.12
|
||||
Feature #5657 - Trial version support
|
||||
Feature #5707 - User upgrade statistics
|
||||
|
||||
v1.8.4-stable
|
||||
=============
|
||||
|
||||
Bug #4041 UHD/4K DPI scaling broken on Windows servers
|
||||
Bug #4420 When XRandR adds a screen, it is inaccessible
|
||||
Bug #5603 Activation notification depends on existence of /etc/os-release
|
||||
Bug #5624 Update notification sometimes requests a downgrade
|
||||
Bug #5329 Current date is shown for build date in the about dialog
|
||||
Bug #5640 Synergy branding is inconsistent across platforms
|
||||
Enhancement #5617 Remove redundant plugin infrastructure
|
||||
Enhancement #5627 Move SSL certificate generation to main window
|
||||
Enhancement #5628 Move SSL implementation into core binary
|
||||
Enhancement #5629 Move activation from wizard into new dialog window
|
||||
Bug #5183 - Slowly moving the cursor has no effect on high DPI clients
|
||||
Bug #4041 - UHD/4K DPI scaling broken on Windows servers
|
||||
Bug #4420 - When XRandR adds a screen, it is inaccessible
|
||||
Bug #5603 - Activation notification depends on existence of /etc/os-release
|
||||
Bug #5624 - Update notification sometimes requests a downgrade
|
||||
Bug #5329 - Current date is shown for build date in the about dialog
|
||||
Enhancement #5617 - Remove redundant plugin infrastructure
|
||||
Enhancement #5627 - Move SSL certificate generation to main window
|
||||
Enhancement #5628 - Move SSL implementation into core binary
|
||||
Enhancement #5629 - Move activation from wizard into new dialog window
|
||||
|
||||
v1.8.3-stable
|
||||
=============
|
||||
|
|
|
@ -435,14 +435,16 @@ class InternalCommands:
|
|||
if generator.cmakeName.find('Unix Makefiles') != -1:
|
||||
cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize()
|
||||
|
||||
elif sys.platform == "darwin":
|
||||
if sys.platform == "darwin":
|
||||
macSdkMatch = re.match("(\d+)\.(\d+)", self.macSdk)
|
||||
if not macSdkMatch:
|
||||
raise Exception("unknown osx version: " + self.macSdk)
|
||||
|
||||
if generator.cmakeName.find('Unix Makefiles') == -1:
|
||||
sdkDir = self.getMacSdkDir()
|
||||
cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir
|
||||
cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macSdk
|
||||
|
||||
cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1)
|
||||
cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2)
|
||||
|
||||
|
@ -558,6 +560,7 @@ class InternalCommands:
|
|||
if os.path.exists(sdkPath):
|
||||
return sdkPath
|
||||
|
||||
# return os.popen('xcodebuild -version -sdk macosx' + self.macSdk + ' Path').read().strip()
|
||||
return "/Developer/SDKs/" + sdkDirName + ".sdk"
|
||||
|
||||
# http://tinyurl.com/cs2rxxb
|
||||
|
|
BIN
res/synergy.ico
BIN
res/synergy.ico
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 281 KiB |
|
@ -35,7 +35,7 @@ else()
|
|||
endif()
|
||||
|
||||
target_link_libraries(synergyd
|
||||
arch base common io ipc mt net platform synergy ${libs} ${OPENSSL_LIBS})
|
||||
arch base common io ipc mt net platform synergy shared ${libs} ${OPENSSL_LIBS})
|
||||
|
||||
if (WIN32)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
|
|
|
@ -7,7 +7,8 @@ DEFINES += VERSION_REVISION=\\\"$$QMAKE_VERSION_REVISION\\\"
|
|||
DEPENDPATH += . \
|
||||
res
|
||||
INCLUDEPATH += . \
|
||||
src
|
||||
src \
|
||||
../lib/shared/
|
||||
FORMS += res/MainWindowBase.ui \
|
||||
res/AboutDialogBase.ui \
|
||||
res/ServerConfigDialogBase.ui \
|
||||
|
@ -60,11 +61,12 @@ SOURCES += src/main.cpp \
|
|||
src/Fingerprint.cpp \
|
||||
src/SslCertificate.cpp \
|
||||
src/WebClient.cpp \
|
||||
src/SubscriptionManager.cpp \
|
||||
src/ActivationNotifier.cpp \
|
||||
src/ActivationDialog.cpp \
|
||||
src/CancelActivationDialog.cpp \
|
||||
src/FailedLoginDialog.cpp
|
||||
src/FailedLoginDialog.cpp \
|
||||
../lib/shared/SerialKey.cpp \
|
||||
src/LicenseManager.cpp
|
||||
HEADERS += src/MainWindow.h \
|
||||
src/AboutDialog.h \
|
||||
src/ServerConfig.h \
|
||||
|
@ -101,18 +103,19 @@ HEADERS += src/MainWindow.h \
|
|||
src/DataDownloader.h \
|
||||
src/AddClientDialog.h \
|
||||
src/CommandProcess.h \
|
||||
src/EditionType.h \
|
||||
src/ProcessorArch.h \
|
||||
src/CoreInterface.h \
|
||||
src/Fingerprint.h \
|
||||
src/SslCertificate.h \
|
||||
src/WebClient.h \
|
||||
src/SubscriptionManager.h \
|
||||
src/ActivationNotifier.h \
|
||||
src/ElevateMode.h \
|
||||
src/ActivationDialog.h \
|
||||
src/CancelActivationDialog.h \
|
||||
src/FailedLoginDialog.h
|
||||
src/FailedLoginDialog.h \
|
||||
../lib/shared/EditionType.h \
|
||||
../lib/shared/SerialKey.h \
|
||||
src/LicenseManager.h
|
||||
RESOURCES += res/Synergy.qrc
|
||||
RC_FILE = res/win/Synergy.rc
|
||||
macx {
|
||||
|
|
|
@ -13,19 +13,25 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>450</width>
|
||||
<height>378</height>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>450</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>450</width>
|
||||
<height>378</height>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -35,20 +41,48 @@
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<property name="text">
|
||||
<string><p>
|
||||
Keyboard and mouse sharing application. Cross platform and open source.<br /><br />
|
||||
Copyright © 2012-2016 Symless Ltd.<br />
|
||||
Copyright © 2002-2012 Chris Schoeneman, Nick Bolton, Volker Lanz.<br /><br />
|
||||
Synergy is released under the GNU General Public License (GPLv2).<br /><br />
|
||||
Synergy is based on CosmoSynergy by Richard Lee and Adam Feder.<br />
|
||||
The Synergy GUI is based on QSynergy by Volker Lanz.<br /><br />
|
||||
Visit our website for help and info (symless.com).
|
||||
</p></string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>450</width>
|
||||
<height>16777215</height>
|
||||
<width>20</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -163,41 +197,6 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Keyboard and mouse sharing application. <br/><br/>Copyright © 2012-2016 Symless Ltd.<br/>Copyright © 2002-2012 Chris Schoeneman, Nick Bolton, Volker Lanz.</p><p>Synergy is based on CosmoSynergy by Richard Lee and Adam Feder.<br/>The Synergy GUI is based on QSynergy by Volker Lanz. </p><p>Synergy is released under the GNU General Public License (GPLv2).</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>440</width>
|
||||
<height>314</height>
|
||||
<width>410</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -15,7 +15,7 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioButtonActivate">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
|
@ -23,83 +23,14 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Account login</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="m_pLabelEmail">
|
||||
<property name="text">
|
||||
<string>Email:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="m_pLineEditEmail">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Normal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="m_pLineEditPassword">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_pRadioButtonSubscription">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Serial key</string>
|
||||
<string>Serial key</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Found on your <a href="https://symless.com/account/?source=gui">account</a> page.</string>
|
||||
<string><html><head/><body><p>This can be found on your <a href="https://symless.com/account/?source=gui"><span style=" text-decoration: underline; color:#0000ff;">account</span></a> page.</p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
|
@ -109,7 +40,10 @@
|
|||
<item>
|
||||
<widget class="QTextEdit" name="m_pTextEditSerialKey">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="tabChangesFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
|
@ -123,6 +57,57 @@ p, li { white-space: pre-wrap; }
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_trialWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/16x16/money.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_trialLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Your trial has expired. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
|
@ -135,7 +120,12 @@ p, li { white-space: pre-wrap; }
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<tabstops>
|
||||
<tabstop>m_pTextEditSerialKey</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="Synergy.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<property name="text">
|
||||
<string>Are you sure?
|
||||
|
||||
If you don't activate Synergy you'll be missing out on some great features</string>
|
||||
If you don't activate Synergy you'll be missing out on some great features.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -27,6 +27,57 @@
|
|||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QWidget" name="m_trialWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_trialLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-weight:600;">%1</span> days of your Synergy Pro trial remain. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetUpdate" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
|
@ -40,7 +91,7 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>7</number>
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pIconUpdate">
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<item>
|
||||
<widget class="QTabWidget" name="m_pTabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_pTabScreens">
|
||||
<attribute name="title">
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 281 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 4.8 KiB |
|
@ -7,39 +7,40 @@
|
|||
#include "ActivationNotifier.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QUtility.h"
|
||||
#include "SubscriptionManager.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "FailedLoginDialog.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
|
||||
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig) :
|
||||
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig,
|
||||
LicenseManager& licenseManager) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ActivationDialog),
|
||||
m_appConfig (&appConfig)
|
||||
m_appConfig(&appConfig),
|
||||
m_LicenseManager (&licenseManager)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
refreshSerialKey();
|
||||
time_t currentTime = ::time(0);
|
||||
if (!m_LicenseManager->serialKey().isExpired(currentTime)) {
|
||||
ui->m_trialWidget->hide();
|
||||
}
|
||||
}
|
||||
|
||||
ui->m_pLineEditEmail->setText(appConfig.activateEmail());
|
||||
ui->m_pTextEditSerialKey->setText(appConfig.serialKey());
|
||||
|
||||
if (!appConfig.serialKey().isEmpty()) {
|
||||
ui->m_pRadioButtonActivate->setAutoExclusive(false);
|
||||
ui->m_pRadioButtonSubscription->setAutoExclusive(false);
|
||||
ui->m_pRadioButtonActivate->setChecked(false);
|
||||
ui->m_pRadioButtonSubscription->setChecked(true);
|
||||
ui->m_pRadioButtonActivate->setAutoExclusive(true);
|
||||
ui->m_pRadioButtonSubscription->setAutoExclusive(true);
|
||||
void ActivationDialog::refreshSerialKey()
|
||||
{
|
||||
ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey());
|
||||
ui->m_pTextEditSerialKey->setFocus();
|
||||
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
|
||||
} else {
|
||||
if (ui->m_pLineEditEmail->text().isEmpty()) {
|
||||
ui->m_pLineEditEmail->setFocus();
|
||||
} else {
|
||||
ui->m_pLineEditPassword->setFocus();
|
||||
}
|
||||
}
|
||||
ui->m_trialLabel->setText(tr("<html><head/><body><p>Your trial has "
|
||||
"expired. <a href=\"https://symless.com/"
|
||||
"synergy/trial/thanks?id=%1\"><span "
|
||||
"style=\"text-decoration: underline; "
|
||||
"color:#0000ff;\">Buy now!</span></a>"
|
||||
"</p></body></html>")
|
||||
.arg (m_appConfig->serialKey()));
|
||||
}
|
||||
|
||||
ActivationDialog::~ActivationDialog()
|
||||
|
@ -47,119 +48,75 @@ ActivationDialog::~ActivationDialog()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void ActivationDialog::notifyActivation(QString identity)
|
||||
{
|
||||
ActivationNotifier* notifier = new ActivationNotifier();
|
||||
notifier->setIdentity(identity);
|
||||
|
||||
QThread* thread = new QThread();
|
||||
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
|
||||
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
notifier->moveToThread(thread);
|
||||
thread->start();
|
||||
|
||||
QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void ActivationDialog::reject()
|
||||
{
|
||||
if (m_LicenseManager->activeEdition() == kUnregistered) {
|
||||
CancelActivationDialog cancelActivationDialog(this);
|
||||
if (QDialog::Accepted == cancelActivationDialog.exec()) {
|
||||
notifyActivation("skip:unknown");
|
||||
m_LicenseManager->skipActivation();
|
||||
m_appConfig->activationHasRun(true);
|
||||
m_appConfig->saveSettings();
|
||||
QDialog::reject();
|
||||
}
|
||||
}
|
||||
|
||||
void ActivationDialog::on_m_pRadioButtonSubscription_toggled(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
ui->m_pLineEditEmail->setEnabled(false);
|
||||
ui->m_pLineEditPassword->setEnabled(false);
|
||||
ui->m_pTextEditSerialKey->setEnabled(true);
|
||||
ui->m_pTextEditSerialKey->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void ActivationDialog::on_m_pRadioButtonActivate_toggled(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
ui->m_pLineEditEmail->setEnabled(true);
|
||||
ui->m_pLineEditPassword->setEnabled(true);
|
||||
ui->m_pTextEditSerialKey->setEnabled(false);
|
||||
if (ui->m_pLineEditEmail->text().isEmpty()) {
|
||||
ui->m_pLineEditEmail->setFocus();
|
||||
} else {
|
||||
ui->m_pLineEditPassword->setFocus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void ActivationDialog::accept()
|
||||
{
|
||||
QMessageBox message;
|
||||
QString error;
|
||||
int edition = Unregistered;
|
||||
|
||||
m_appConfig->activationHasRun(true);
|
||||
m_appConfig->saveSettings();
|
||||
|
||||
std::pair<bool, QString> result;
|
||||
try {
|
||||
if (ui->m_pRadioButtonActivate->isChecked()) {
|
||||
WebClient webClient;
|
||||
QString email = ui->m_pLineEditEmail->text();
|
||||
QString password = ui->m_pLineEditPassword->text();
|
||||
|
||||
if (!webClient.setEmail (email, error)) {
|
||||
message.critical (this, "Invalid Email Address", tr("%1").arg(error));
|
||||
return;
|
||||
}
|
||||
else if (!webClient.setPassword (password, error)) {
|
||||
message.critical (this, "Invalid Password", tr("%1").arg(error));
|
||||
return;
|
||||
}
|
||||
else if (!webClient.getEdition (edition, error)) {
|
||||
FailedLoginDialog failedLoginDialog (this, error);
|
||||
failedLoginDialog.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
m_appConfig->setActivateEmail (email);
|
||||
m_appConfig->clearSerialKey();
|
||||
ui->m_pTextEditSerialKey->clear();
|
||||
notifyActivation ("login:" + m_appConfig->activateEmail());
|
||||
}
|
||||
else {
|
||||
QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
|
||||
|
||||
if (!m_appConfig->setSerialKey (serialKey, error)) {
|
||||
message.critical (this, "Invalid Serial Key", tr("%1").arg(error));
|
||||
return;
|
||||
}
|
||||
|
||||
SubscriptionManager subscriptionManager (this, *m_appConfig, edition);
|
||||
if (!subscriptionManager.activateSerial (serialKey)) {
|
||||
return;
|
||||
}
|
||||
m_appConfig->setActivateEmail("");
|
||||
notifyActivation ("serial:" + m_appConfig->serialKey());
|
||||
}
|
||||
QString serialKey = ui->m_pTextEditSerialKey->toPlainText().trimmed();
|
||||
result = m_LicenseManager->setSerialKey(serialKey);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
message.critical (this, "Unknown Error",
|
||||
message.critical(this, "Unknown Error",
|
||||
tr("An error occurred while trying to activate Synergy. "
|
||||
"Please contact the helpdesk, and provide the "
|
||||
"following details.\n\n%1").arg(e.what()));
|
||||
"following information:\n\n%1").arg(e.what()));
|
||||
refreshSerialKey();
|
||||
return;
|
||||
}
|
||||
|
||||
m_appConfig->setEdition(edition);
|
||||
m_appConfig->saveSettings();
|
||||
if (!result.first) {
|
||||
message.critical(this, "Activation failed",
|
||||
tr("%1").arg(result.second));
|
||||
refreshSerialKey();
|
||||
return;
|
||||
}
|
||||
|
||||
m_LicenseManager->notifyActivation("serial:" + m_appConfig->serialKey());
|
||||
Edition edition = m_LicenseManager->activeEdition();
|
||||
time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
|
||||
if (edition != kUnregistered) {
|
||||
QString thanksMessage = tr("Thanks for trying %1! %5\n\n%2 day%3 of "
|
||||
"your trial remain%4").
|
||||
arg (m_LicenseManager->getEditionName(edition)).
|
||||
arg (daysLeft).
|
||||
arg ((daysLeft == 1) ? "" : "s").
|
||||
arg ((daysLeft == 1) ? "s" : "");
|
||||
|
||||
if (edition == kPro) {
|
||||
thanksMessage = thanksMessage.arg("If you're using SSL, "
|
||||
"remember to activate all of your devices.");
|
||||
} else {
|
||||
thanksMessage = thanksMessage.arg("");
|
||||
}
|
||||
|
||||
if (m_LicenseManager->serialKey().isTrial()) {
|
||||
message.information(this, "Thanks!", thanksMessage);
|
||||
}
|
||||
else {
|
||||
message.information(this, "Activated!",
|
||||
tr("Thanks for activating %1!").arg
|
||||
(m_LicenseManager->getEditionName(edition)));
|
||||
}
|
||||
}
|
||||
|
||||
message.information (this, "Activated!",
|
||||
tr("Thanks for activating %1!").arg (getEditionName (edition)));
|
||||
QDialog::accept();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define ACTIVATIONDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <LicenseManager.h>
|
||||
|
||||
namespace Ui {
|
||||
class ActivationDialog;
|
||||
|
@ -14,7 +15,8 @@ class ActivationDialog : public QDialog
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ActivationDialog(QWidget *parent, AppConfig& appConfig);
|
||||
ActivationDialog(QWidget *parent, AppConfig& appConfig,
|
||||
LicenseManager& licenseManager);
|
||||
~ActivationDialog();
|
||||
|
||||
public slots:
|
||||
|
@ -22,15 +24,12 @@ public slots:
|
|||
void accept();
|
||||
|
||||
protected:
|
||||
void notifyActivation (QString identity);
|
||||
void refreshSerialKey();
|
||||
|
||||
private:
|
||||
Ui::ActivationDialog *ui;
|
||||
AppConfig* m_appConfig;
|
||||
|
||||
private slots:
|
||||
void on_m_pRadioButtonSubscription_toggled(bool checked);
|
||||
void on_m_pRadioButtonActivate_toggled(bool checked);
|
||||
LicenseManager* m_LicenseManager;
|
||||
};
|
||||
|
||||
#endif // ACTIVATIONDIALOG_H
|
||||
|
|
|
@ -29,6 +29,15 @@ void ActivationNotifier::setIdentity(QString identity)
|
|||
m_Identity = identity;
|
||||
}
|
||||
|
||||
void ActivationNotifier::setUpdateInfo(QString const& fromVersion,
|
||||
QString const& toVersion,
|
||||
QString const& serialKey)
|
||||
{
|
||||
m_fromVersion = fromVersion;
|
||||
m_toVersion = toVersion;
|
||||
m_serialKey = serialKey;
|
||||
}
|
||||
|
||||
void ActivationNotifier::notify()
|
||||
{
|
||||
CoreInterface coreInterface;
|
||||
|
@ -39,3 +48,13 @@ void ActivationNotifier::notify()
|
|||
// catch all exceptions and fails silently
|
||||
}
|
||||
}
|
||||
|
||||
void ActivationNotifier::notifyUpdate()
|
||||
{
|
||||
try {
|
||||
CoreInterface coreInterface;
|
||||
coreInterface.notifyUpdate(m_fromVersion, m_toVersion,
|
||||
m_serialKey);
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,15 +27,21 @@ public:
|
|||
explicit ActivationNotifier(QObject *parent = 0);
|
||||
|
||||
void setIdentity(QString identity);
|
||||
void setUpdateInfo(QString const& fromVersion,
|
||||
QString const& toVersion, QString const& serialKey);
|
||||
|
||||
public slots:
|
||||
void notify();
|
||||
void notifyUpdate();
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
QString m_Identity;
|
||||
QString m_fromVersion;
|
||||
QString m_toVersion;
|
||||
QString m_serialKey;
|
||||
};
|
||||
|
||||
#endif // ACTIVATIONNOTIFIER_H
|
||||
|
|
|
@ -157,11 +157,12 @@ void AppConfig::loadSettings()
|
|||
}
|
||||
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
||||
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
|
||||
m_Edition = settings().value("edition", Unregistered).toInt();
|
||||
m_Edition = static_cast<Edition>(settings().value("edition", kUnregistered).toInt());
|
||||
m_ActivateEmail = settings().value("activateEmail", "").toString();
|
||||
m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool();
|
||||
m_AutoHide = settings().value("autoHide", false).toBool();
|
||||
m_Serialkey = settings().value("serialKey", "").toString();
|
||||
m_lastVersion = settings().value("lastVersion", "Unknown").toString();
|
||||
m_LastExpiringWarningTime = settings().value("lastExpiringWarningTime", 0).toInt();
|
||||
m_ActivationHasRun = settings().value("activationHasRun", false).toBool();
|
||||
}
|
||||
|
@ -184,10 +185,10 @@ void AppConfig::saveSettings()
|
|||
settings().setValue("elevateModeEnum", static_cast<int>(m_ElevateMode));
|
||||
settings().setValue("autoConfigPrompted", m_AutoConfigPrompted);
|
||||
settings().setValue("edition", m_Edition);
|
||||
settings().setValue("activateEmail", m_ActivateEmail);
|
||||
settings().setValue("cryptoEnabled", m_CryptoEnabled);
|
||||
settings().setValue("autoHide", m_AutoHide);
|
||||
settings().setValue("serialKey", m_Serialkey);
|
||||
settings().setValue("lastVersion", m_lastVersion);
|
||||
settings().setValue("lastExpiringWarningTime", m_LastExpiringWarningTime);
|
||||
settings().setValue("activationHasRun", m_ActivationHasRun);
|
||||
settings().sync();
|
||||
|
@ -204,6 +205,15 @@ AppConfig& AppConfig::activationHasRun(bool value)
|
|||
return *this;
|
||||
}
|
||||
|
||||
QString AppConfig::lastVersion() const
|
||||
{
|
||||
return m_lastVersion;
|
||||
}
|
||||
|
||||
void AppConfig::setLastVersion(QString version) {
|
||||
m_lastVersion = version;
|
||||
}
|
||||
|
||||
QSettings &AppConfig::settings() { return *m_pSettings; }
|
||||
|
||||
void AppConfig::setScreenName(const QString &s) { m_ScreenName = s; }
|
||||
|
@ -238,27 +248,16 @@ void AppConfig::setAutoConfigPrompted(bool prompted)
|
|||
m_AutoConfigPrompted = prompted;
|
||||
}
|
||||
|
||||
void AppConfig::setEdition(int e) {
|
||||
void AppConfig::setEdition(Edition e) {
|
||||
m_Edition = e;
|
||||
emit editionSet (e);
|
||||
}
|
||||
|
||||
int AppConfig::edition() const { return m_Edition; }
|
||||
Edition AppConfig::edition() const { return m_Edition; }
|
||||
|
||||
bool AppConfig::setActivateEmail(QString e) {
|
||||
m_ActivateEmail = e;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString AppConfig::activateEmail() { return m_ActivateEmail; }
|
||||
|
||||
bool AppConfig::setSerialKey(QString serial, QString& errorOut) {
|
||||
if (serial.isEmpty()) {
|
||||
errorOut = "Your serial key cannot be blank.";
|
||||
return false;
|
||||
}
|
||||
m_Serialkey = serial;
|
||||
return true;
|
||||
QString AppConfig::setSerialKey(QString serial) {
|
||||
using std::swap;
|
||||
swap (serial, m_Serialkey);
|
||||
return serial;
|
||||
}
|
||||
|
||||
void AppConfig::clearSerialKey()
|
||||
|
@ -287,7 +286,7 @@ void AppConfig::setCryptoEnabled(bool e) {
|
|||
}
|
||||
|
||||
bool AppConfig::getCryptoEnabled() const {
|
||||
return (edition() == Pro) && m_CryptoEnabled;
|
||||
return (edition() == kPro) && m_CryptoEnabled;
|
||||
}
|
||||
|
||||
void AppConfig::setAutoHide(bool b) { m_AutoHide = b; }
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
#include "ElevateMode.h"
|
||||
#include <EditionType.h>
|
||||
|
||||
// this should be incremented each time a new page is added. this is
|
||||
// saved to settings when the user finishes running the wizard. if
|
||||
|
@ -78,11 +79,9 @@ class AppConfig: public QObject
|
|||
void setAutoConfig(bool autoConfig);
|
||||
bool autoConfigPrompted();
|
||||
void setAutoConfigPrompted(bool prompted);
|
||||
void setEdition(int e);
|
||||
int edition() const;
|
||||
bool setActivateEmail(QString e);
|
||||
QString activateEmail();
|
||||
bool setSerialKey(QString serial, QString& error);
|
||||
void setEdition(Edition);
|
||||
Edition edition() const;
|
||||
QString setSerialKey(QString serial);
|
||||
void clearSerialKey();
|
||||
QString serialKey();
|
||||
int lastExpiringWarningTime() const;
|
||||
|
@ -106,9 +105,12 @@ class AppConfig: public QObject
|
|||
bool activationHasRun() const;
|
||||
AppConfig& activationHasRun(bool value);
|
||||
|
||||
void saveSettings();
|
||||
QString lastVersion() const;
|
||||
|
||||
protected:
|
||||
void saveSettings();
|
||||
void setLastVersion(QString version);
|
||||
|
||||
protected:
|
||||
QSettings& settings();
|
||||
void setScreenName(const QString& s);
|
||||
void setPort(int i);
|
||||
|
@ -137,11 +139,12 @@ class AppConfig: public QObject
|
|||
bool m_AutoConfig;
|
||||
ElevateMode m_ElevateMode;
|
||||
bool m_AutoConfigPrompted;
|
||||
int m_Edition;
|
||||
Edition m_Edition;
|
||||
QString m_ActivateEmail;
|
||||
bool m_CryptoEnabled;
|
||||
bool m_AutoHide;
|
||||
QString m_Serialkey;
|
||||
QString m_lastVersion;
|
||||
int m_LastExpiringWarningTime;
|
||||
bool m_ActivationHasRun;
|
||||
|
||||
|
@ -150,7 +153,6 @@ class AppConfig: public QObject
|
|||
static const char m_SynergyLogDir[];
|
||||
|
||||
signals:
|
||||
void editionSet(int);
|
||||
void sslToggled(bool enabled);
|
||||
};
|
||||
|
||||
|
|
|
@ -22,20 +22,22 @@
|
|||
|
||||
#include <QCoreApplication>
|
||||
#include <QProcess>
|
||||
#include <QtGlobal>
|
||||
#include <QDir>
|
||||
#include <stdexcept>
|
||||
|
||||
static const char kCoreBinary[] = "syntool";
|
||||
|
||||
#ifdef Q_WS_WIN
|
||||
static const char kSerialKeyFilename[] = "Synergy.subkey";
|
||||
#else
|
||||
static const char kSerialKeyFilename[] = ".synergy.subkey";
|
||||
#endif
|
||||
|
||||
CoreInterface::CoreInterface()
|
||||
{
|
||||
}
|
||||
|
||||
QString CoreInterface::getPluginDir()
|
||||
{
|
||||
QStringList args("--get-plugin-dir");
|
||||
return run(args);
|
||||
}
|
||||
|
||||
QString CoreInterface::getProfileDir()
|
||||
{
|
||||
QStringList args("--get-profile-dir");
|
||||
|
@ -54,24 +56,19 @@ QString CoreInterface::getArch()
|
|||
return run(args);
|
||||
}
|
||||
|
||||
QString CoreInterface::getSubscriptionFilename()
|
||||
QString CoreInterface::getSerialKeyFilePath()
|
||||
{
|
||||
QStringList args("--get-subscription-filename");
|
||||
return run(args);
|
||||
QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
|
||||
return filename;
|
||||
}
|
||||
|
||||
QString CoreInterface::activateSerial(const QString& serial)
|
||||
{
|
||||
QStringList args("--subscription-serial");
|
||||
args << serial;
|
||||
|
||||
return run(args);
|
||||
}
|
||||
|
||||
QString CoreInterface::checkSubscription()
|
||||
{
|
||||
QStringList args("--check-subscription");
|
||||
return run(args);
|
||||
QString CoreInterface::notifyUpdate (QString const& fromVersion,
|
||||
QString const& toVersion,
|
||||
QString const& serialKey) {
|
||||
QStringList args("--notify-update");
|
||||
QString input(fromVersion + ":" + toVersion + ":" + serialKey);
|
||||
input.append("\n");
|
||||
return run(args, input);
|
||||
}
|
||||
|
||||
QString CoreInterface::notifyActivation(const QString& identity)
|
||||
|
|
|
@ -24,13 +24,13 @@ class CoreInterface
|
|||
public:
|
||||
CoreInterface();
|
||||
|
||||
QString getPluginDir();
|
||||
QString getProfileDir();
|
||||
QString getInstalledDir();
|
||||
QString getArch();
|
||||
QString getSubscriptionFilename();
|
||||
QString activateSerial(const QString& serial);
|
||||
QString checkSubscription();
|
||||
QString getSerialKeyFilePath();
|
||||
QString notifyActivation(const QString& identity);
|
||||
QString notifyUpdate (QString const& fromVersion,
|
||||
QString const& toVersion,
|
||||
QString const& serialKey);
|
||||
QString run(const QStringList& args, const QString& input = "");
|
||||
};
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LicenseManager.h"
|
||||
#include "EditionType.h"
|
||||
#include "AppConfig.h"
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <QThread>
|
||||
|
||||
LicenseManager::LicenseManager(AppConfig* appConfig) :
|
||||
m_AppConfig(appConfig),
|
||||
m_serialKey(appConfig->edition()) {
|
||||
}
|
||||
|
||||
std::pair<bool, QString>
|
||||
LicenseManager::setSerialKey(QString serialKeyString, bool acceptExpired)
|
||||
{
|
||||
std::pair<bool, QString> ret (true, "");
|
||||
time_t currentTime = ::time(0);
|
||||
SerialKey serialKey (serialKeyString.toStdString());
|
||||
|
||||
if (!acceptExpired && serialKey.isExpired(currentTime)) {
|
||||
ret.first = false;
|
||||
ret.second = "Serial key expired";
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (serialKey != m_serialKey) {
|
||||
using std::swap;
|
||||
swap (serialKey, m_serialKey);
|
||||
m_AppConfig->setSerialKey(serialKeyString);
|
||||
emit serialKeyChanged(m_serialKey);
|
||||
|
||||
if (serialKey.isTrial()) {
|
||||
emit endTrial(false);
|
||||
}
|
||||
|
||||
if (m_serialKey.edition() != serialKey.edition()) {
|
||||
m_AppConfig->setEdition(m_serialKey.edition());
|
||||
emit editionChanged(m_serialKey.edition());
|
||||
}
|
||||
|
||||
if (m_serialKey.isTrial()) {
|
||||
if (m_serialKey.isExpired(currentTime)) {
|
||||
emit endTrial(true);
|
||||
} else {
|
||||
emit beginTrial(m_serialKey.isExpiring(currentTime));
|
||||
}
|
||||
}
|
||||
|
||||
m_AppConfig->saveSettings();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
LicenseManager::notifyUpdate(QString fromVersion, QString toVersion) {
|
||||
if ((fromVersion == "Unknown")
|
||||
&& (m_serialKey == SerialKey(kUnregistered))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ActivationNotifier* notifier = new ActivationNotifier();
|
||||
notifier->setUpdateInfo (fromVersion, toVersion,
|
||||
QString::fromStdString(m_serialKey.toString()));
|
||||
|
||||
QThread* thread = new QThread();
|
||||
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
|
||||
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
notifier->moveToThread(thread);
|
||||
thread->start();
|
||||
|
||||
QMetaObject::invokeMethod(notifier, "notifyUpdate",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
Edition
|
||||
LicenseManager::activeEdition() const
|
||||
{
|
||||
return m_serialKey.edition();
|
||||
}
|
||||
|
||||
QString
|
||||
LicenseManager::activeEditionName() const
|
||||
{
|
||||
return getEditionName(activeEdition(), m_serialKey.isTrial());
|
||||
}
|
||||
|
||||
SerialKey
|
||||
LicenseManager::serialKey() const
|
||||
{
|
||||
return m_serialKey;
|
||||
}
|
||||
|
||||
void LicenseManager::refresh()
|
||||
{
|
||||
if (!m_AppConfig->serialKey().isEmpty()) {
|
||||
setSerialKey(m_AppConfig->serialKey(), true);
|
||||
}
|
||||
if (m_serialKey.isExpired(::time(0))) {
|
||||
emit endTrial(true);
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseManager::skipActivation()
|
||||
{
|
||||
notifyActivation ("skip:unknown");
|
||||
}
|
||||
|
||||
QString
|
||||
LicenseManager::getEditionName(Edition const edition, bool trial)
|
||||
{
|
||||
std::string name ("Synergy");
|
||||
switch (edition) {
|
||||
case kUnregistered:
|
||||
name += " (UNREGISTERED)";
|
||||
return QString::fromUtf8 (name.c_str(), name.size());
|
||||
case kBasic:
|
||||
name += " Basic";
|
||||
break;
|
||||
default:
|
||||
name += " Pro";
|
||||
}
|
||||
if (trial) {
|
||||
name += " (Trial)";
|
||||
}
|
||||
return QString::fromUtf8 (name.c_str(), name.size());
|
||||
}
|
||||
|
||||
void LicenseManager::notifyActivation(QString identity)
|
||||
{
|
||||
ActivationNotifier* notifier = new ActivationNotifier();
|
||||
notifier->setIdentity(identity);
|
||||
|
||||
QThread* thread = new QThread();
|
||||
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
|
||||
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
notifier->moveToThread(thread);
|
||||
thread->start();
|
||||
|
||||
QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <SerialKey.h>
|
||||
#include <ActivationNotifier.h>
|
||||
#include <utility>
|
||||
|
||||
class AppConfig;
|
||||
|
||||
class LicenseManager: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LicenseManager(AppConfig* appConfig);
|
||||
std::pair<bool, QString> 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;
|
||||
};
|
|
@ -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 ("<html><head/><body><p><span style=\""
|
||||
"font-weight:600;\">%1</span> day%3 of "
|
||||
"your %2 trial remain%5. <a href="
|
||||
"\"https://symless.com/synergy/trial/thanks?id=%4\">"
|
||||
"<span style=\"text-decoration: underline;"
|
||||
" color:#0000ff;\">Buy now!</span></a>"
|
||||
"</p></body></html>");
|
||||
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 (
|
||||
"<html><head/><body><p>Your %1 trial has expired. <a href="
|
||||
"\"https://symless.com/synergy/trial/thanks?id=%2\">"
|
||||
"<span style=\"text-decoration: underline;color:#0000ff;\">"
|
||||
"Buy now!</span></a></p></body></html>"
|
||||
);
|
||||
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()
|
||||
|
@ -1325,16 +1422,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 )
|
||||
|
@ -1380,11 +1477,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ class ZeroconfService;
|
|||
class DataDownloader;
|
||||
class CommandProcess;
|
||||
class SslCertificate;
|
||||
class LicenseManager;
|
||||
|
||||
class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||
{
|
||||
|
@ -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);
|
||||
|
|
|
@ -42,22 +42,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();
|
||||
|
|
|
@ -29,4 +29,3 @@ QString hash(const QString& string);
|
|||
QString getFirstMacAddress();
|
||||
qProcessorArch getProcessorArch();
|
||||
QString getOSInformation();
|
||||
QString getEditionName (int edition);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SubscriptionManager.h"
|
||||
|
||||
|
||||
#include "CoreInterface.h"
|
||||
#include "EditionType.h"
|
||||
#include "AppConfig.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
#include <QDate>
|
||||
|
||||
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 <a href='%1'>here</a> 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 <a href='%3'>here</a> 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(".");
|
||||
}
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
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;
|
||||
};
|
|
@ -20,6 +20,7 @@
|
|||
#define TRAY_RETRY_WAIT 2000
|
||||
|
||||
#include "QSynergyApplication.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "AppConfig.h"
|
||||
#include "SetupWizard.h"
|
||||
|
@ -82,11 +83,13 @@ int main(int argc, char* argv[])
|
|||
#endif
|
||||
|
||||
QSettings settings;
|
||||
AppConfig appConfig(&settings);
|
||||
AppConfig appConfig (&settings);
|
||||
qRegisterMetaType<Edition>("Edition");
|
||||
LicenseManager licenseManager (&appConfig);
|
||||
|
||||
app.switchTranslator(appConfig.language());
|
||||
|
||||
MainWindow mainWindow(settings, appConfig);
|
||||
MainWindow mainWindow(settings, appConfig, licenseManager);
|
||||
SetupWizard setupWizard(mainWindow, true);
|
||||
|
||||
if (appConfig.wizardShouldRun())
|
||||
|
|
|
@ -25,7 +25,7 @@ add_subdirectory(net)
|
|||
add_subdirectory(platform)
|
||||
add_subdirectory(server)
|
||||
add_subdirectory(synergy)
|
||||
|
||||
add_subdirectory(shared)
|
||||
|
||||
if (WIN32)
|
||||
add_subdirectory(synwinhk)
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
||||
|
|
|
@ -42,13 +42,6 @@ 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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ public:
|
|||
// IListenSocket overrides
|
||||
virtual IDataSocket*
|
||||
accept();
|
||||
void deleteSocket(void*);
|
||||
|
||||
private:
|
||||
typedef std::set<IDataSocket*> SecureSocketSet;
|
||||
|
|
|
@ -43,7 +43,6 @@ public:
|
|||
// IListenSocket overrides
|
||||
virtual IDataSocket*
|
||||
accept();
|
||||
virtual void deleteSocket(void*) { }
|
||||
|
||||
protected:
|
||||
void setListeningJob();
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -122,7 +122,7 @@ OSXClipboard::add(EFormat format, const String & data)
|
|||
|
||||
PasteboardPutItemFlavor(
|
||||
m_pboard,
|
||||
(PasteboardItemID) 0,
|
||||
nullptr,
|
||||
flavorType,
|
||||
dataRef,
|
||||
kPasteboardFlavorNoFlags);
|
||||
|
|
|
@ -344,4 +344,6 @@ private:
|
|||
Mutex* m_carbonLoopMutex;
|
||||
CondVar<bool>* m_carbonLoopReady;
|
||||
#endif
|
||||
|
||||
class OSXScreenImpl* m_impl;
|
||||
};
|
||||
|
|
|
@ -101,7 +101,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();
|
||||
|
@ -515,9 +516,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)
|
|
@ -35,6 +35,8 @@ endif()
|
|||
|
||||
add_library(server STATIC ${sources})
|
||||
|
||||
target_link_libraries(server shared)
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(server synergy)
|
||||
endif()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -48,8 +48,6 @@ public:
|
|||
|
||||
//@}
|
||||
|
||||
void deleteSocket(void* socket);
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
|
|
|
@ -45,11 +45,13 @@
|
|||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "common/stdexcept.h"
|
||||
#include "shared/SerialKey.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
|
||||
//
|
||||
// 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<Server>(this,
|
||||
&Server::handleFakeInputEndEvent));
|
||||
|
||||
if (m_enableDragDrop) {
|
||||
if (m_args.m_enableDragDrop) {
|
||||
m_events->adoptHandler(m_events->forFile().fileChunkSending(),
|
||||
this,
|
||||
new TMethodEventJob<Server>(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;
|
||||
|
@ -1378,10 +1387,7 @@ Server::handleClientDisconnected(const Event&, void* vclient)
|
|||
removeActiveClient(client);
|
||||
removeOldClient(client);
|
||||
|
||||
PacketStreamFilter* streamFileter = dynamic_cast<PacketStreamFilter*>(client->getStream());
|
||||
TCPSocket* socket = dynamic_cast<TCPSocket*>(streamFileter->getStream());
|
||||
delete client;
|
||||
m_clientListener->deleteSocket(socket);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1391,10 +1397,8 @@ Server::handleClientCloseTimeout(const Event&, void* vclient)
|
|||
BaseClientProxy* client = static_cast<BaseClientProxy*>(vclient);
|
||||
LOG((CLOG_NOTE "forced disconnection of client \"%s\"", getName(client).c_str()));
|
||||
removeOldClient(client);
|
||||
PacketStreamFilter* streamFileter = dynamic_cast<PacketStreamFilter*>(client->getStream());
|
||||
TCPSocket* socket = dynamic_cast<TCPSocket*>(streamFileter->getStream());
|
||||
|
||||
delete client;
|
||||
m_clientListener->deleteSocket(socket);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1706,7 +1710,7 @@ Server::onMouseUp(ButtonID id)
|
|||
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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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)
|
||||
|
|
@ -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
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SerialKey.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <climits>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <stdexcept>
|
||||
|
||||
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<int>(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<char>(((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<string> 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;
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#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);
|
||||
}
|
|
@ -74,6 +74,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;
|
||||
|
@ -193,18 +196,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;
|
||||
|
@ -213,26 +208,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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
ServerArgs::ServerArgs() :
|
||||
m_configFile(),
|
||||
m_serial(),
|
||||
m_config(NULL)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
};
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
//#include <stdexcept>
|
||||
|
||||
#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<char>(((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<String> 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<int>(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;
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
};
|
|
@ -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,8 +138,26 @@ ToolApp::loginAuth()
|
|||
}
|
||||
|
||||
void
|
||||
ToolApp::getPluginList()
|
||||
ToolApp::notifyUpdate()
|
||||
{
|
||||
String data;
|
||||
std::cin >> data;
|
||||
|
||||
std::vector<String> 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
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
|
||||
private:
|
||||
void loginAuth();
|
||||
void getPluginList();
|
||||
void notifyActivation();
|
||||
void notifyUpdate();
|
||||
|
||||
private:
|
||||
ToolArgs m_args;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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));
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
Loading…
Reference in New Issue