diff --git a/ChangeLog b/ChangeLog index f187e4c4f..039c46d52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ Bug fixes: - #6760 Synergy loses license when creating a System scope config - #6342 Updated copyright year in version to use build date - #6771 Added Ubuntu 16 to CI/CD +- #6792 License key expiry Enhancements: - #6750 Integrate SonarCloud for static analysis and test coverage diff --git a/src/gui/src/ActivationDialog.cpp b/src/gui/src/ActivationDialog.cpp index e8136107f..9033ad709 100644 --- a/src/gui/src/ActivationDialog.cpp +++ b/src/gui/src/ActivationDialog.cpp @@ -30,16 +30,10 @@ ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig, void ActivationDialog::refreshSerialKey() { - ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey()); - ui->m_pTextEditSerialKey->setFocus(); - ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End); - ui->m_trialLabel->setText(tr("

Your trial has " - "expired. Buy now!" - "

") - .arg (m_appConfig->serialKey())); + ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey()); + ui->m_pTextEditSerialKey->setFocus(); + ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End); + ui->m_trialLabel->setText(tr(m_LicenseManager->getLicenseNotice().toStdString().c_str())); } ActivationDialog::~ActivationDialog() diff --git a/src/gui/src/LicenseManager.cpp b/src/gui/src/LicenseManager.cpp index f0f09c2f3..cd4272c59 100644 --- a/src/gui/src/LicenseManager.cpp +++ b/src/gui/src/LicenseManager.cpp @@ -46,29 +46,22 @@ LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) (m_serialKey.toString())); emit serialKeyChanged(m_serialKey); - if (serialKey.isTrial()) { - emit endTrial(false); + emit showLicenseNotice(getLicenseNotice()); + if (m_serialKey.isExpired(currentTime)) { + emit LicenseExpired(); } 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)); - } - } } return ret; } void -LicenseManager::notifyUpdate(QString fromVersion, QString toVersion) { +LicenseManager::notifyUpdate(QString fromVersion, QString toVersion) const { if ((fromVersion == "Unknown") && (m_serialKey == SerialKey(kUnregistered))) { return; @@ -108,7 +101,8 @@ LicenseManager::serialKey() const return m_serialKey; } -void LicenseManager::refresh() +void +LicenseManager::refresh() { if (!m_AppConfig->serialKey().isEmpty()) { try { @@ -119,11 +113,12 @@ void LicenseManager::refresh() } } if (m_serialKey.isExpired(::time(0))) { - emit endTrial(true); + emit LicenseExpired(); } } -void LicenseManager::skipActivation() +void +LicenseManager::skipActivation() const { notifyActivation ("skip:unknown"); } @@ -131,7 +126,7 @@ void LicenseManager::skipActivation() QString LicenseManager::getEditionName(Edition const edition, bool trial) { - std::string name ("Synergy 1"); + std::string name ("Synergy 1"); switch (edition) { case kUnregistered: name += " (UNREGISTERED)"; @@ -148,7 +143,8 @@ LicenseManager::getEditionName(Edition const edition, bool trial) return QString::fromUtf8 (name.c_str(), static_cast(name.size())); } -void LicenseManager::notifyActivation(QString identity) +void +LicenseManager::notifyActivation(QString identity) const { ActivationNotifier* notifier = new ActivationNotifier(); notifier->setIdentity(identity); @@ -163,3 +159,79 @@ void LicenseManager::notifyActivation(QString identity) QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection); } + +QString +LicenseManager::getLicenseNotice() const +{ + QString Notice; + + if (m_serialKey.isTemporary()){ + if (m_serialKey.isTrial()){ + Notice = getTrialNotice(); + } + else{ + Notice = getTemporaryNotice(); + } + } + + return Notice; +} + +QString +LicenseManager::getTrialNotice() const +{ + QString Notice; + + if (m_serialKey.isExpired(::time(0))){ + Notice = "

Your %1 trial has expired. " + "" + "Buy now!

"; + Notice = Notice.arg(LicenseManager::getEditionName(activeEdition())); + } + else{ + Notice = "

%1 day%3 of " + "your %2 trial remain%5. " + "Buy now!" + "

"; + + time_t daysLeft = m_serialKey.daysLeft(::time(0)); + Notice = Notice + .arg (daysLeft) + .arg (LicenseManager::getEditionName(activeEdition())) + .arg ((daysLeft == 1) ? "" : "s") + .arg ((daysLeft == 1) ? "s" : ""); + } + + return Notice; +} + +QString +LicenseManager::getTemporaryNotice() const +{ + QString Notice; + + if (m_serialKey.isExpired(::time(0))) { + Notice = "

Your license has expired. " + "" + "Renew now!

"; + } + else if (m_serialKey.isExpiring(::time(0))) { + Notice = "

%1 day%2 " + "before your license expires." + "Renew now!" + "

"; + + time_t daysLeft = m_serialKey.daysLeft(::time(0)); + Notice = Notice.arg (daysLeft).arg ((daysLeft == 1) ? "" : "s"); + } + + return Notice; +} diff --git a/src/gui/src/LicenseManager.h b/src/gui/src/LicenseManager.h index 88fdbb59f..823354939 100644 --- a/src/gui/src/LicenseManager.h +++ b/src/gui/src/LicenseManager.h @@ -37,10 +37,11 @@ public: 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); + void skipActivation() const; + void notifyUpdate(QString fromVersion, QString toVersion) const; + static QString getEditionName(Edition edition, bool trial = false); + void notifyActivation(QString identity) const; + QString getLicenseNotice() const; private: AppConfig* m_AppConfig; @@ -49,6 +50,10 @@ private: signals: void serialKeyChanged (SerialKey) const; void editionChanged (Edition) const; - void beginTrial (bool expiring) const; - void endTrial (bool expired) const; + void LicenseExpired () const; + void showLicenseNotice(const QString& notice) const; + +protected: + QString getTrialNotice() const; + QString getTemporaryNotice() const; }; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 2bcf21776..dee6eee77 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -171,11 +171,11 @@ MainWindow::MainWindow (AppConfig& appConfig, 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(showLicenseNotice(QString)), + this, SLOT(showLicenseNotice(QString)), Qt::QueuedConnection); - connect (m_LicenseManager, SIGNAL(endTrial(bool)), - this, SLOT(endTrial(bool)), Qt::QueuedConnection); + connect (m_LicenseManager, SIGNAL(LicenseExpired()), + this, SLOT(LicenseExpired()), Qt::QueuedConnection); #endif connect (m_AppConfig, SIGNAL(sslToggled(bool)), @@ -1152,54 +1152,21 @@ void MainWindow::setEdition(Edition edition) } #ifndef SYNERGY_ENTERPRISE -void MainWindow::beginTrial(bool isExpiring) +void MainWindow::LicenseExpired() { - //Hack - //if (isExpiring) { - time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0)); - QString expiringNotice ("

%1 day%3 of " - "your %2 trial remain%5. " - "Buy now!" - "

"); - expiringNotice = expiringNotice - .arg (daysLeft) - .arg (LicenseManager::getEditionName - (m_LicenseManager->activeEdition())) - .arg ((daysLeft == 1) ? "" : "s") - .arg (QString::fromStdString - (m_LicenseManager->serialKey().toString())) - .arg ((daysLeft == 1) ? "s" : ""); - this->m_trialLabel->setText(expiringNotice); - this->m_trialWidget->show(); - //} - setWindowTitle (m_LicenseManager->activeEditionName()); + stopSynergy(); + m_AppConfig->activationHasRun(false); } -void MainWindow::endTrial(bool isExpired) +void MainWindow::showLicenseNotice(const QString& notice) { - if (isExpired) { - QString expiredNotice ( - "

Your %1 trial has expired. " - "" - "Buy now!

" - ); - expiredNotice = expiredNotice - .arg(LicenseManager::getEditionName - (m_LicenseManager->activeEdition())) - .arg(QString::fromStdString - (m_LicenseManager->serialKey().toString())); + this->m_trialWidget->hide(); - this->m_trialLabel->setText(expiredNotice); + if (!notice.isEmpty()) { + this->m_trialLabel->setText(notice); this->m_trialWidget->show(); - stopSynergy(); - m_AppConfig->activationHasRun(false); - } else { - this->m_trialWidget->hide(); } + setWindowTitle (m_LicenseManager->activeEditionName()); } #endif diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 0dd60c80e..280ba22d4 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -132,8 +132,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase public slots: void setEdition(Edition edition); #ifndef SYNERGY_ENTERPRISE - void beginTrial(bool isExpiring); - void endTrial(bool isExpired); + void LicenseExpired(); + void showLicenseNotice(const QString& message); #endif void appendLogRaw(const QString& text); void appendLogInfo(const QString& text); diff --git a/src/lib/shared/SerialKey.cpp b/src/lib/shared/SerialKey.cpp index b3e7d3c8f..f7c1118c2 100644 --- a/src/lib/shared/SerialKey.cpp +++ b/src/lib/shared/SerialKey.cpp @@ -27,89 +27,94 @@ #include using namespace std; +static std::string hexEncode (std::string const& str); SerialKey::SerialKey(Edition edition): - m_userLimit(1), - m_warnTime(ULLONG_MAX), - m_expireTime(ULLONG_MAX), - m_edition(edition), - m_trial(false) + m_userLimit(1), + m_warnTime(ULLONG_MAX), + m_expireTime(ULLONG_MAX), + m_edition(edition) { } SerialKey::SerialKey(std::string serial) : - m_userLimit(1), - m_warnTime(0), - m_expireTime(0), - m_edition(kBasic), - m_trial(true) + m_userLimit(1), + m_warnTime(0), + m_expireTime(0), + m_edition(kBasic) { - string plainText = decode(serial); - bool valid = false; - if (!plainText.empty()) { - valid = parse(plainText); - } - if (!valid) { - throw std::runtime_error ("Invalid serial key"); - } + 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; + bool result = false; - if (m_trial) { + if (isTemporary()) { unsigned long long currentTimeAsLL = static_cast(currentTime); - if ((m_warnTime <= currentTimeAsLL) && (currentTimeAsLL < m_expireTime)) { - result = true; - } - } + if ((m_warnTime <= currentTimeAsLL) && (currentTimeAsLL < m_expireTime)) { + result = true; + } + } - return result; + return result; } bool SerialKey::isExpired(time_t currentTime) const { - bool result = false; + bool result = false; - if (m_trial) { + if (isTemporary()) { unsigned long long currentTimeAsLL = static_cast(currentTime); - if (m_expireTime <= currentTimeAsLL) { - result = true; - } - } + if (m_expireTime <= currentTimeAsLL) { + result = true; + } + } - return result; + return result; } bool SerialKey::isTrial() const { - return m_trial; + return m_KeyType.isTrial(); +} + +bool +SerialKey::isTemporary() const +{ + return m_KeyType.isTemporary(); } Edition SerialKey::edition() const { - return m_edition; + return m_edition; } std::string SerialKey::editionString() const { - switch (edition()) { - case kBasic: - return "basic"; - case kPro: - return "pro"; - default: { - std::ostringstream oss; - oss << static_cast(edition()); - return oss.str(); - } - } + switch (edition()) { + case kBasic: + return "basic"; + case kPro: + return "pro"; + default: { + std::ostringstream oss; + oss << static_cast(edition()); + return oss.str(); + } + } } static std::string @@ -128,141 +133,145 @@ hexEncode (std::string const& 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()); + std::ostringstream oss; + oss << "{"; + if (isTemporary()) { + if (isTrial()){ + oss << "v2;" << SerialKeyType::TRIAL << ";"; + } + else{ + oss << "v2;" << SerialKeyType::SUBSCRIPTION << ";"; + } + } else { + oss << "v1;"; + } + oss << editionString() << ";"; + oss << m_name << ";"; + oss << m_userLimit << ";"; + oss << m_email << ";"; + oss << m_company << ";"; + oss << (isTemporary() ? m_warnTime : 0) << ";"; + oss << (isTemporary() ? 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; + unsigned long long timeLeft = 0; + unsigned long long const day = 60 * 60 * 24; unsigned long long currentTimeAsLL = static_cast(currentTime); - if (currentTimeAsLL < m_expireTime) { - timeLeft = m_expireTime - currentTimeAsLL; - } + if (currentTimeAsLL < m_expireTime) { + timeLeft = m_expireTime - currentTimeAsLL; + } - unsigned long long daysLeft = 0; - daysLeft = timeLeft % day != 0 ? 1 : 0; + unsigned long long daysLeft = 0; + daysLeft = timeLeft % day != 0 ? 1 : 0; - return timeLeft / day + daysLeft; + return timeLeft / day + daysLeft; } std::string SerialKey::email() const { - return m_email; + 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; - } + 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) { + output.reserve(len / 2); + for (size_t i = 0; i < len; i += 2) { - char a = serial[i]; - char b = serial[i + 1]; + 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); + 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; - } + if (*q != b || *p != a) { + return output; + } - output.push_back(static_cast(((p - lut) << 4) | (q - lut))); - } + output.push_back(static_cast(((p - lut) << 4) | (q - lut))); + } - return output; + return output; } bool SerialKey::parse(std::string plainSerial) { - string parityStart = plainSerial.substr(0, 1); - string parityEnd = plainSerial.substr(plainSerial.length() - 1, 1); + string parityStart = plainSerial.substr(0, 1); + string parityEnd = plainSerial.substr(plainSerial.length() - 1, 1); - bool valid = false; + bool valid = false; - // check for parity chars { and }, record parity result, then remove them. - if (parityStart == "{" && parityEnd == "}") { - plainSerial = plainSerial.substr(1, plainSerial.length() - 2); + // check for parity chars { and }, record parity result, then remove them. + if (parityStart == "{" && parityEnd == "}") { + plainSerial = plainSerial.substr(1, plainSerial.length() - 2); - // tokenize serialised subscription. - vector parts; - std::string::size_type pos = 0; - bool look = true; - while (look) { - std::string::size_type start = pos; - pos = plainSerial.find(";", pos); - if (pos == string::npos) { - pos = plainSerial.length(); - look = false; - } - parts.push_back(plainSerial.substr(start, pos - start)); - pos += 1; - } + // tokenize serialised subscription. + vector parts; + std::string::size_type pos = 0; + bool look = true; + while (look) { + std::string::size_type start = pos; + pos = plainSerial.find(";", pos); + if (pos == string::npos) { + pos = plainSerial.length(); + look = false; + } + parts.push_back(plainSerial.substr(start, pos - start)); + pos += 1; + } - if ((parts.size() == 8) - && (parts.at(0).find("v1") != string::npos)) { - // e.g.: {v1;basic;Bob;1;email;company name;1398297600;1398384000} - m_edition = parseEdition(parts.at(1)); - m_name = parts.at(2); - m_trial = false; - sscanf(parts.at(3).c_str(), "%d", &m_userLimit); - m_email = parts.at(4); - m_company = parts.at(5); - sscanf(parts.at(6).c_str(), "%lld", &m_warnTime); - sscanf(parts.at(7).c_str(), "%lld", &m_expireTime); - valid = true; - } - else if ((parts.size() == 9) - && (parts.at(0).find("v2") != string::npos)) { - // e.g.: {v2;trial;basic;Bob;1;email;company name;1398297600;1398384000} - m_trial = parts.at(1) == "trial" ? true : false; - m_edition = parseEdition(parts.at(2)); - m_name = parts.at(3); - sscanf(parts.at(4).c_str(), "%d", &m_userLimit); - m_email = parts.at(5); - m_company = parts.at(6); - sscanf(parts.at(7).c_str(), "%lld", &m_warnTime); - sscanf(parts.at(8).c_str(), "%lld", &m_expireTime); - valid = true; - } - } + 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); + 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_KeyType.setKeyType(parts.at(1)); + 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; + return valid; } Edition SerialKey::parseEdition(std::string const& editionStr) { - Edition e = kBasic; - if (editionStr == "pro") { - e = kPro; - } + Edition e = kBasic; + if (editionStr == "pro") { + e = kPro; + } - return e; + return e; } diff --git a/src/lib/shared/SerialKey.h b/src/lib/shared/SerialKey.h index a27382cca..b8b78636f 100644 --- a/src/lib/shared/SerialKey.h +++ b/src/lib/shared/SerialKey.h @@ -20,6 +20,7 @@ #include #include #include "EditionType.h" +#include "SerialKeyType.h" #ifdef TEST_ENV #include @@ -34,6 +35,7 @@ public: bool isExpiring(time_t currentTime) const; bool isExpired(time_t currentTime) const; bool isTrial() const; + bool isTemporary() const; time_t daysLeft(time_t currentTime) const; std::string email() const; Edition edition() const; @@ -55,14 +57,14 @@ private: #endif private: - std::string m_name; - std::string m_email; - std::string m_company; - unsigned m_userLimit; + 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; + Edition m_edition; + SerialKeyType m_KeyType; }; @@ -75,7 +77,7 @@ operator== (SerialKey const& lhs, SerialKey const& rhs) { (lhs.m_warnTime == rhs.m_warnTime) && (lhs.m_expireTime == rhs.m_expireTime) && (lhs.m_edition == rhs.m_edition) && - (lhs.m_trial == rhs.m_trial); + (lhs.m_KeyType == rhs.m_KeyType); } inline bool diff --git a/src/lib/shared/SerialKeyType.cpp b/src/lib/shared/SerialKeyType.cpp new file mode 100644 index 000000000..ff3ae7aa8 --- /dev/null +++ b/src/lib/shared/SerialKeyType.cpp @@ -0,0 +1,60 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2015 Synergy Seamless Inc. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "SerialKeyType.h" + +const std::string SerialKeyType::TRIAL = "trial"; +const std::string SerialKeyType::SUBSCRIPTION = "subscription"; + +SerialKeyType::SerialKeyType() +{ + +} + +void +SerialKeyType::setKeyType(const std::string& Type) +{ + m_isTrial = false; + m_isTemporary = false; + + if (Type == SerialKeyType::TRIAL){ + m_isTrial = true; + m_isTemporary = true; + } + else if (Type == SerialKeyType::SUBSCRIPTION){ + m_isTemporary = true; + } +} + +bool +SerialKeyType::isTrial() const +{ + return m_isTrial; +} + +bool +SerialKeyType::isTemporary() const +{ + return m_isTemporary; +} + +bool +SerialKeyType::isPermanent() const +{ + return (!m_isTemporary); +} + diff --git a/src/lib/shared/SerialKeyType.h b/src/lib/shared/SerialKeyType.h new file mode 100644 index 000000000..bd1154d16 --- /dev/null +++ b/src/lib/shared/SerialKeyType.h @@ -0,0 +1,50 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2016 Symless Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include + +class SerialKeyType +{ +private: + friend bool operator== (SerialKeyType const&, SerialKeyType const&); +public: + static const std::string TRIAL; + static const std::string SUBSCRIPTION; + + SerialKeyType(); + + void setKeyType(const std::string& Type); + bool isTrial() const; + bool isTemporary() const; + bool isPermanent() const; + +private: + bool m_isTrial = false; + bool m_isTemporary = false; +}; + +inline bool +operator== (SerialKeyType const& lhs, SerialKeyType const& rhs) { + return (lhs.m_isTrial == rhs.m_isTrial) && (lhs.m_isTemporary == rhs.m_isTemporary); +} + +inline bool +operator!= (SerialKeyType const& lhs, SerialKeyType const& rhs) { + return !(lhs == rhs); +} + diff --git a/src/test/unittests/shared/SerialKeyTests.cpp b/src/test/unittests/shared/SerialKeyTests.cpp index 37d811d45..e2dcd005f 100644 --- a/src/test/unittests/shared/SerialKeyTests.cpp +++ b/src/test/unittests/shared/SerialKeyTests.cpp @@ -74,6 +74,7 @@ TEST(SerialKeyTests, parse_validV2Serial_valid) EXPECT_EQ(true, serial.daysLeft(0)); EXPECT_EQ(true, serial.isExpiring(1)); EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); } TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse) @@ -81,6 +82,7 @@ TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse) // {v2;trial;basic;Bob;1;email;company name;1;86400} SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B313B38363430307D"); EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); EXPECT_FALSE(serial.isExpiring(0)); EXPECT_EQ(kBasic, serial.edition()); } @@ -90,6 +92,7 @@ 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.isTemporary()); EXPECT_EQ(true, serial.isExpiring(1)); } @@ -98,6 +101,7 @@ TEST(SerialKeyTests, isExpiring_expiredV2TrialBasicSerial_returnFalse) // {v2;trial;basic;Bob;1;email;company name;0;86400} SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); EXPECT_FALSE(serial.isExpiring(86401)); } @@ -106,6 +110,7 @@ TEST(SerialKeyTests, isExpired_validV2TrialBasicSerial_returnFalse) // {v2;trial;basic;Bob;1;email;company name;0;86400} SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); EXPECT_FALSE(serial.isExpired(0)); } @@ -114,6 +119,7 @@ TEST(SerialKeyTests, isExpired_expiringV2TrialBasicSerial_returnFalse) // {v2;trial;basic;Bob;1;email;company name;0;86400} SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); EXPECT_FALSE(serial.isExpired(1)); } @@ -122,6 +128,7 @@ 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.isTemporary()); EXPECT_EQ(true, serial.isExpired(86401)); } @@ -145,3 +152,59 @@ TEST(SerialKeyTests, daysLeft_expiredV2TrialBasicSerial_returnZero) SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); EXPECT_EQ(0, serial.daysLeft(86401)); } + +//Subscription license tests +TEST(SerialKeyTests, isExpiring_validV2SubscriptionBasicSerial_returnFalse) +{ + // {v2;subscription;basic;Bob;1;email;company name;1;86400} + SerialKey serial("7B76323B737562736372697074696F6E3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B313B38363430307D"); + EXPECT_EQ(false, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); + EXPECT_FALSE(serial.isExpiring(0)); + EXPECT_EQ(kBasic, serial.edition()); +} + +TEST(SerialKeyTests, isExpiring_expiringV2SubscriptionBasicSerial_returnTrue) +{ + // {v2;subscription;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B737562736372697074696F6E3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(false, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); + EXPECT_EQ(true, serial.isExpiring(1)); +} + +TEST(SerialKeyTests, isExpired_expiredV2SubscriptionBasicSerial_returnTrue) +{ + // {v2;subscription;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B737562736372697074696F6E3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(false, serial.isTrial()); + EXPECT_EQ(true, serial.isTemporary()); + EXPECT_EQ(true, serial.isExpired(86401)); +} + +//toString method tests +TEST(SerialKeyTests, toStringV2SubscriptionBasicSerialKey) +{ + //{v2;subscription;basic;Bob;1;email;company name;0;86400} + const std::string Expected = "7B76323B737562736372697074696F6E3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"; + SerialKey serial(Expected); + EXPECT_EQ(Expected, serial.toString()); +} + +TEST(SerialKeyTests, toStringV2TrialBasicSerialKey) +{ + //{v2;trial;basic;Bob;1;email;company name;0;86400} + const std::string Expected = "7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"; + SerialKey serial(Expected); + EXPECT_EQ(Expected, serial.toString()); +} + +TEST(SerialKeyTests, toStringV1BasicSerialKey) +{ + //{v1;basic;Bob;1;email;company name;0;0} + const std::string Expected = "7B76313B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B307D"; + SerialKey serial(Expected); + EXPECT_EQ(Expected, serial.toString()); +} + + diff --git a/src/test/unittests/shared/SerialKeyTypeTests.cpp b/src/test/unittests/shared/SerialKeyTypeTests.cpp new file mode 100644 index 000000000..66f1ca9ce --- /dev/null +++ b/src/test/unittests/shared/SerialKeyTypeTests.cpp @@ -0,0 +1,57 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2016 Symless Inc. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define TEST_ENV + +#include "shared/SerialKeyType.h" + +#include "test/global/gtest.h" + +TEST(SerialKeyTypeTests, TrialTemporaryKeyType_false) +{ + SerialKeyType KeyType; + EXPECT_EQ(false, KeyType.isTrial()); + EXPECT_EQ(false, KeyType.isTemporary()); + EXPECT_EQ(true, KeyType.isPermanent()); +} + +TEST(SerialKeyTypeTests, TrialTemporaryKeyType_true) +{ + SerialKeyType KeyType; + KeyType.setKeyType("trial"); + EXPECT_EQ(true, KeyType.isTrial()); + EXPECT_EQ(true, KeyType.isTemporary()); + EXPECT_EQ(false, KeyType.isPermanent()); +} + +TEST(SerialKeyTypeTests, TemporaryKeyType_true) +{ + SerialKeyType KeyType; + KeyType.setKeyType("subscription"); + EXPECT_EQ(false, KeyType.isTrial()); + EXPECT_EQ(true, KeyType.isTemporary()); + EXPECT_EQ(false, KeyType.isPermanent()); +} + +TEST(SerialKeyTypeTests, PermanentKeyType_true) +{ + SerialKeyType KeyType; + KeyType.setKeyType(""); + EXPECT_EQ(false, KeyType.isTrial()); + EXPECT_EQ(false, KeyType.isTemporary()); + EXPECT_EQ(true, KeyType.isPermanent()); +}