From bfdd664a763c0f6b28f21d7f976a7189e0bf1c10 Mon Sep 17 00:00:00 2001 From: Serhii Hadzhilov <71632867+SerhiiGadzhilov@users.noreply.github.com> Date: Mon, 18 Jul 2022 16:13:29 +0300 Subject: [PATCH] License registration for Business edition (#7203) * License registration for business * Rename register to registry * Add email into the request * Add decoded serial key into the request * Revert "Add decoded serial key into the request" This reverts commit 0e18c8941664e86ae2264bbef072df68cab07751. * Revert "Add email into the request" This reverts commit 8dff01bc242769008897947d66187cb726fb34bf. * Change field guid_generated to guid_type * Update ChangeLog * Update ChangeLog --- ChangeLog | 1 + src/gui/src/AppConfig.cpp | 24 ++++++++- src/gui/src/AppConfig.h | 15 +++++- src/gui/src/LicenseManager.cpp | 10 +++- src/gui/src/LicenseManager.h | 4 ++ src/gui/src/LicenseRegistry.cpp | 96 +++++++++++++++++++++++++++++++++ src/gui/src/LicenseRegistry.h | 43 +++++++++++++++ src/gui/src/MainWindow.cpp | 1 + 8 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 src/gui/src/LicenseRegistry.cpp create mode 100644 src/gui/src/LicenseRegistry.h diff --git a/ChangeLog b/ChangeLog index cd47436ede..abb355a4e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ Enhancements: - #7190 Maintenance license serial key support - #7193 Support for maintenance licenses in China - #7197 Special contributor mentions on the about screen +- #7203 License registration for Business edition 1.14.4 ====== diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 89f1821020..338765a754 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -247,6 +247,9 @@ void AppConfig::loadSettings() m_LanguageSync = loadSetting(kLanguageSync, false).toBool(); m_InvertScrollDirection = loadSetting(kInvertScrollDirection, false).toBool(); m_eliteBackersUrl = loadCommonSetting(kEliteBackersUrl, "https://api2.prod.symless.com/credits/elite-backers").toString(); + m_guid = loadCommonSetting(kGuid, QSysInfo::machineUniqueId()).toString(); + m_licenseRegistryUrl = loadCommonSetting(kLicenseRegistryUrl, "https://api2.prod.symless.com/license/register").toString(); + m_licenseNextCheck = loadCommonSetting(kLicenseNextCheck, 0).toULongLong(); //only change the serial key if the settings being loaded contains a key bool updateSerial = ConfigWriter::make() @@ -280,6 +283,9 @@ void AppConfig::saveSettings() setCommonSetting(kGroupClientCheck, m_ClientGroupChecked); setCommonSetting(kGroupServerCheck, m_ServerGroupChecked); setCommonSetting(kEliteBackersUrl, m_eliteBackersUrl); + setCommonSetting(kGuid, m_guid); + setCommonSetting(kLicenseRegistryUrl, m_licenseRegistryUrl); + setCommonSetting(kLicenseNextCheck, m_licenseNextCheck); if (isWritable()) { setSetting(kScreenName, m_ScreenName); @@ -408,7 +414,7 @@ void AppConfig::clearSerialKey() m_Serialkey.clear(); } -QString AppConfig::serialKey() { return m_Serialkey; } +QString AppConfig::serialKey() const { return m_Serialkey; } int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; } @@ -472,10 +478,26 @@ void AppConfig::setEliteBackersUrl(const QString& newValue) { setSettingModified(m_eliteBackersUrl, newValue); } +void AppConfig::setLicenseNextCheck(unsigned long long time) { + setSettingModified(m_licenseNextCheck, time); +} + const QString& AppConfig::getEliteBackersUrl() const { return m_eliteBackersUrl; } +const QString& AppConfig::getLicenseRegistryUrl() const { + return m_licenseRegistryUrl; +} + +unsigned long long AppConfig::getLicenseNextCheck() const { + return m_licenseNextCheck; +} + +const QString& AppConfig::getGuid() const { + return m_guid; +} + bool AppConfig::getLanguageSync() const { return m_LanguageSync; } void AppConfig::setInvertScrollDirection(bool newValue) { diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 072cd714e7..87e155e357 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -50,6 +50,7 @@ const int kWizardVersion = 8; class QSettings; class SettingsDialog; class ServerConfig; +class LicenseRegister; enum ProcessMode { Service, @@ -93,7 +94,7 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase Edition edition() const; void setSerialKey(const QString& serial); void clearSerialKey(); - QString serialKey(); + QString serialKey() const; int lastExpiringWarningTime() const; void setLastExpiringWarningTime(int t); #endif @@ -115,7 +116,11 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase void setInvertScrollDirection(bool b); bool getInvertScrollDirection() const; void setEliteBackersUrl(const QString&); + void setLicenseNextCheck(unsigned long long); const QString& getEliteBackersUrl() const; + const QString& getLicenseRegistryUrl() const; + unsigned long long getLicenseNextCheck() const; + const QString& getGuid() const; void setLanguageSync(bool b); bool getLanguageSync() const; void setPreventSleep(bool b); @@ -211,7 +216,10 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase kPreventSleep, kLanguageSync, kInvertScrollDirection, - kEliteBackersUrl + kEliteBackersUrl, + kGuid, + kLicenseRegistryUrl, + kLicenseNextCheck }; void setScreenName(const QString& s); @@ -252,6 +260,9 @@ class AppConfig: public QObject, public GUI::Config::ConfigBase QString m_Serialkey; QString m_lastVersion; QString m_eliteBackersUrl; + QString m_guid; + QString m_licenseRegistryUrl; + unsigned long long m_licenseNextCheck; int m_LastExpiringWarningTime; bool m_ActivationHasRun; bool m_MinimizeToTray; diff --git a/src/gui/src/LicenseManager.cpp b/src/gui/src/LicenseManager.cpp index 49d66c081a..b4c899b364 100644 --- a/src/gui/src/LicenseManager.cpp +++ b/src/gui/src/LicenseManager.cpp @@ -66,7 +66,8 @@ checkSerialKey(const SerialKey& serialKey, bool acceptExpired) LicenseManager::LicenseManager(AppConfig* appConfig) : m_AppConfig(appConfig), - m_serialKey(appConfig->edition()) { + m_serialKey(appConfig->edition()), + m_registry(*appConfig) { } void @@ -82,6 +83,7 @@ LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) emit showLicenseNotice(getLicenseNotice()); validateSerialKey(); + m_registry.scheduleRegistration(); if (m_serialKey.edition() != serialKey.edition()) { m_AppConfig->setEdition(m_serialKey.edition()); @@ -201,6 +203,12 @@ LicenseManager::getLicenseNotice() const return Notice; } +void +LicenseManager::registerLicense() +{ + m_registry.registerLicense(); +} + QString LicenseManager::getTrialNotice() const { diff --git a/src/gui/src/LicenseManager.h b/src/gui/src/LicenseManager.h index 101cb299ea..1c9feeefb4 100644 --- a/src/gui/src/LicenseManager.h +++ b/src/gui/src/LicenseManager.h @@ -23,6 +23,8 @@ #include <ActivationNotifier.h> #include <utility> +#include "LicenseRegistry.h" + class AppConfig; class LicenseManager: public QObject @@ -45,9 +47,11 @@ class LicenseManager: public QObject private: AppConfig* m_AppConfig; SerialKey m_serialKey; + LicenseRegistry m_registry; public slots: void validateSerialKey() const; + void registerLicense(); signals: void editionChanged (Edition) const; diff --git a/src/gui/src/LicenseRegistry.cpp b/src/gui/src/LicenseRegistry.cpp new file mode 100644 index 0000000000..943275436f --- /dev/null +++ b/src/gui/src/LicenseRegistry.cpp @@ -0,0 +1,96 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 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 <QNetworkReply> +#include <QJsonObject> +#include <QJsonDocument> +#include <QTimer> + +#include "LicenseRegistry.h" +#include "AppConfig.h" +#include <QSysInfo> + +LicenseRegistry::LicenseRegistry(AppConfig& config) : + m_config(config) +{ + connect(&m_timer, SIGNAL(timeout()), this, SLOT(registerLicense())); +} + +void LicenseRegistry::registerLicense() +{ + m_timer.stop(); + if (m_config.edition() == Edition::kBusiness) { + const auto REGISTER_LICENSE_URL = m_config.getLicenseRegistryUrl(); + const auto url = QUrl(REGISTER_LICENSE_URL); + + auto request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + auto reply = m_manager.post(request, getRequestData()); + connect(reply, &QNetworkReply::finished, [=]() { + const auto HOUR = (60*60); //seconds per hour + const auto DAY = (24*HOUR);//seconds per day + const auto WEEK = (7*DAY); //seconds per week + const auto currentTimestamp = time(nullptr); + + if(reply->error() == QNetworkReply::NoError) { + m_config.setLicenseNextCheck(currentTimestamp + WEEK); + } + else{ + m_config.setLicenseNextCheck(currentTimestamp + HOUR); + } + + scheduleRegistration(); + reply->deleteLater(); + }); + } +} + +QByteArray LicenseRegistry::getRequestData() const +{ + QJsonObject data; + QString guid(QSysInfo::machineUniqueId()); + + if (!guid.isEmpty()) { + data["guid"] = guid; + data["guid_type"] = "system"; + } + else { + data["guid"] = m_config.getGuid(); + data["guid_type"] = "synergy"; + } + + data["key"] = m_config.serialKey(); + data["is_server"] = m_config.getServerGroupChecked(); + + return QJsonDocument(data).toJson(); +} + +void LicenseRegistry::scheduleRegistration() +{ + const auto nextCheck = m_config.getLicenseNextCheck(); + const auto currentTimestamp = static_cast<unsigned long long>(time(nullptr)); + + if (currentTimestamp >= nextCheck) { + registerLicense(); + } + else { + const auto interval = (nextCheck - currentTimestamp) * 1000; //interval in milliseconds + m_timer.setInterval(interval); + m_timer.setSingleShot(true); + m_timer.start(); + } +} diff --git a/src/gui/src/LicenseRegistry.h b/src/gui/src/LicenseRegistry.h new file mode 100644 index 0000000000..da3fc3e1df --- /dev/null +++ b/src/gui/src/LicenseRegistry.h @@ -0,0 +1,43 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2022 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 <QTimer> +#include <QNetworkAccessManager> + +class QNetworkReply; +class AppConfig; + +class LicenseRegistry : public QObject +{ + Q_OBJECT + +public: + LicenseRegistry(AppConfig& config); + void scheduleRegistration(); + +public slots: + void registerLicense(); + +private: + AppConfig& m_config; + QNetworkAccessManager m_manager; + QTimer m_timer; + + QByteArray getRequestData() const; +}; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index c6592248cf..a592cecb2b 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -646,6 +646,7 @@ void MainWindow::startSynergy() return; } } + m_LicenseManager->registerLicense(); #endif bool desktopMode = appConfig().processMode() == Desktop; bool serviceMode = appConfig().processMode() == Service;