logic: license seats, startscreen

* license info on startscreen
* volume license
* license generator update
This commit is contained in:
Andreas Stallinger
2017-03-03 13:49:05 +01:00
parent a1d8100215
commit f5dfafe091
11 changed files with 184 additions and 46 deletions
+2 -6
View File
@@ -599,17 +599,13 @@ if (WIN32)
elseif (UNIX)
add_custom_command(
OUTPUT ${TESTGEN_FILE}
TARGET ${TEST_PROJECT_NAME}
PRE_BUILD
COMMAND rm -f ${TESTGEN_FILE}
#COMMAND rm -f ${TESTGEN_FILE}
COMMAND cd ${PROJECT_SOURCE_DIR} && ${PYTHON_EXECUTABLE} ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE} --runner=ParenPrinter -o ${TESTGEN_FILE} ${TEST_FILES}
COMMENT "Generating unittest code with cxxtestgen"
)
add_custom_target(gen DEPENDS ${TESTGEN_FILE})
add_dependencies(${TEST_PROJECT_NAME} gen)
endif ()
# Visual Leak Detector ---------------------------------------------------------
@@ -47,6 +47,17 @@
font-size: 12px;
}
#licenseHeaderLabel {
color: black;
font-size: 12px;
font-weight: bold;
}
#licenseLabel {
color: black;
font-size: 12px;
}
#welcomeLabel {
color: black;
font-size: 12px;
+1
View File
@@ -21,6 +21,7 @@ if (UNIX AND NOT APPLE)
LLVMCONFIG
llvm-config
PATHS "${CLANG_BUILD_PATH}/bin"
HINTS "${CLANG_BUILD_PATH}/bin"
)
execute_process(
COMMAND ${LLVMCONFIG} --cxxflags
@@ -173,19 +173,14 @@ void IDECommunicationController::handlePing(const NetworkProtocolHelper::PingMes
if (message.valid)
{
MessagePingReceived msg;
msg.ideId = message.ideId;
msg.ideName = message.ideId;
std::string ideName = "unknown";
if (msg.ideId == "vs")
if (msg.ideName.empty())
{
ideName = "Visual Studio";
msg.ideName = "unknown";
}
// TODO: add the other ides
msg.ideName = ideName;
std::string statusMessage = ideName + " instance detected via plugin port";
std::string statusMessage = msg.ideName + " instance detected via plugin port";
MessageStatus(statusMessage, false, false).dispatch();
msg.dispatch();
+19 -1
View File
@@ -16,6 +16,8 @@
#include "qt/utility/utilityQt.h"
#include "utility/logging/logging.h"
#include "utility/Version.h"
#include "License.h"
#include "utility/AppPath.h"
QtRecentProjectButton::QtRecentProjectButton(QWidget* parent)
: QPushButton(parent)
@@ -95,7 +97,7 @@ QSize QtStartScreen::sizeHint() const
void QtStartScreen::updateButtons()
{
std::vector<FilePath> recentProjects = ApplicationSettings::getInstance()->getRecentProjects();
size_t i = 0;
size_t i = 0;
for (QtRecentProjectButton* button : m_recentProjectsButtons)
{
button->disconnect();
@@ -207,6 +209,22 @@ void QtStartScreen::setupStartScreen(bool unlocked)
updateLabel->setObjectName("updateLabel");
col->addWidget(updateLabel);
col->addSpacing(20);
License license;
license.loadFromEncodedString(
ApplicationSettings::getInstance()->getLicenseString(), AppPath::getAppPath());
std::string licenseString = license.getLicenseInfo();
QLabel* licenseHeader = new QLabel("Licensed to:");
licenseHeader->setObjectName("licenseHeaderLabel");
col->addWidget(licenseHeader);
col->addSpacing(2);
QLabel* licenseLabel = new QLabel(licenseString.c_str());
licenseLabel->setObjectName("licenseLabel");
col->addWidget(licenseLabel);
col->addStretch();
QPushButton* newProjectButton = new QPushButton("New Project", this);
+30 -19
View File
@@ -59,7 +59,7 @@ std::string Generator::encodeLicense(const std::string& user, const int days)
boost::gregorian::date expireDate = today + daysToTry;
std::string testLicenseTypeString = "Test License - valid till " + boost::gregorian::to_simple_string(expireDate);
return encodeLicense(user, testLicenseTypeString);
return encodeLicense(user, testLicenseTypeString);
}
std::string Generator::encodeLicense(const std::string& user, const std::string& licenseType, const int seats)
@@ -67,35 +67,46 @@ std::string Generator::encodeLicense(const std::string& user, const std::string&
if (user.size() <= 0)
{
std::cout << "No user given" << std::endl;
return "";
return "";
}
if (licenseType.size() <= 0)
{
std::cout << "No licence type given" << std::endl;
return "";
return "";
}
License license;
//load private key
std::string filename = getPrivateKeyFilename();
std::shared_ptr<Botan::Private_Key> privateKey(
Botan::PKCS8::load_key(filename, m_rng, PRIVATE_KEY_PASSWORD));
Botan::RSA_PrivateKey *rsaKey = dynamic_cast<Botan::RSA_PrivateKey *>(privateKey.get());
if (!rsaKey)
{
std::cout << "The key is not a RSA key" << std::endl;
if (!m_privateKey)
{
std::cout << "No private key. Trying to load from file." << std::endl;
loadPrivateKeyFromFile();
}
license.create(user, m_version, rsaKey, licenseType, seats);
license.writeToFile("license.txt");
license.print();
if (!m_privateKey)
{
std::cout << "No private key. Load from file or string." << std::endl;
return "";
}
return license.getLicenseString();
m_license = std::make_shared<License>();
m_license->create(user, m_version, m_privateKey.get(), licenseType, seats);
return m_license->getLicenseString();
}
void Generator::printLicenseAndWriteItToFile()
{
if (m_license)
{
m_license->print();
m_license->writeToFile("license.txt");
}
else
{
std::cout << "nothing to print" << std::endl;
}
}
bool Generator::verifyLicense(const std::string& filename)
+5 -3
View File
@@ -10,6 +10,7 @@ namespace Botan
{
class RSA_PrivateKey;
}
class License;
class Generator
{
@@ -17,8 +18,9 @@ public:
Generator(const std::string& version = "x");
~Generator();
std::string encodeLicense(const std::string& message, const std::string& licenseType, const int seats = 0);
std::string encodeLicense(const std::string& message, const int days);
std::string encodeLicense(const std::string& user, const std::string& licenseType, const int seats = 0);
std::string encodeLicense(const std::string& user, const int days);
void printLicenseAndWriteItToFile();
bool verifyLicense(const std::string& filename = "license.txt");
void generateKeys();
void writeKeysToFiles();
@@ -45,7 +47,7 @@ private:
std::string m_version;
std::string m_privateKeyFile;
std::string m_publicKeyFile;
std::string m_license;
std::shared_ptr<License> m_license;
std::shared_ptr<Botan::RSA_PrivateKey> m_privateKey;
const std::string PRIVATE_KEY_PASSWORD = "BA#jk5vbklAiKL9K3k$";
+54 -6
View File
@@ -139,21 +139,69 @@ unsigned int License::getSeats() const
return 0;
}
std::string License::getLicenseType() const
{
std::string licenseTypeLine = getLicenseTypeLine();
std::size_t found = licenseTypeLine.find(":");
if (found != licenseTypeLine.npos)
{
return licenseTypeLine.substr(0,found);
}
const std::string testLicenseString = "Test License";
found = licenseTypeLine.find(testLicenseString);
if (found != licenseTypeLine.npos)
{
return "Test License";
}
return licenseTypeLine;
}
std::string License::getLicenseInfo() const
{
std::string info = getOwnerLine() + "\n";
const std::string typeString = getLicenseType();
info += getLicenseType() + "\n";
// get info depending on license type
if (typeString == "Private/Academic Single User License")
{
info += "not registered for commercial development";
}
else if (typeString == "Test License")
{
const std::string t = "Test License - ";
info += getLicenseTypeLine().substr(t.length()) + "\nunlimited Seats";
}
else if (getSeats() > 1)
{
info += std::to_string(getSeats()) + " Seats";
}
else
{
info += "1 Seat";
}
return info;
}
int License::getTimeLeft() const
{
const std::string testText = "Test License - valid till ";
const int leMagicNumber = 11;
const std::string dateText = "YYYY-MMM-DD";
std::string licenceType = getLicenseTypeLine();
if (licenceType.size() <= (testText.length() + leMagicNumber))
if (licenceType.length() != (testText.length() + dateText.length()))
{
return -2; // well, since it's unclear what type of licence...??
return -2; // well, since it's unclear what type of licence...??
}
if(licenceType.substr(0, testText.length()) == testText)
{
std::string dateString = licenceType.substr(testText.length(), leMagicNumber);
std::string dateString = licenceType.substr(testText.length(), dateText.length());
boost::gregorian::date expireDate(
boost::gregorian::from_simple_string(dateString));
@@ -291,10 +339,10 @@ void License::addSignature(const std::string& signature)
}
std::stringstream ss;
const int leMagicNumber = 55; // what does this number mean? signature length?
const int lineLength = 55;
for (size_t i = 0; i < signature.size(); i++)
{
if(i % leMagicNumber == 0 && i != 0)
if(i % lineLength == 0 && i != 0)
{
m_lines.push_back(ss.str());
ss.str("");
+2
View File
@@ -24,7 +24,9 @@ public:
std::string getVersionLine() const;
std::string getOwnerLine() const;
std::string getLicenseTypeLine() const;
std::string getLicenseType() const;
std::string getLicenseInfo() const;
std::string getPublicKeyFilename() const;
std::string getVersion() const;
unsigned int getSeats() const;
+13 -2
View File
@@ -35,7 +35,6 @@ bool process_command_line(int argc, char** argv)
po::options_description keygen_description("Options Keygeneration");
keygen_description.add_options()
("seats,s", po::value<int>(&seats), "Generate a License, USERNAME as value")
("version,v", po::value<std::string>(&version), "Versionnumber of Coati")
("licenseType,t", po::value<std::string>(&type), "License Type of ")
("testLicense,e", po::value<int>(&days), "Generates a test license for <value> days");
@@ -61,12 +60,22 @@ bool process_command_line(int argc, char** argv)
po::notify(vm);
// display help if no argument or the help argument is given
if (vm.count("help") || vm.size() == 0)
if (vm.count("help"))
{
std::cout << desc << std::endl;
return 1;
}
// no mode chosen -> display help
if ( vm.size() == 0 || !(vm.count("hidden") || vm.count("key") || vm.count("check") || vm.count("generate")))
{
std::cout << "*****************************\nNo mode chosen, display help: "
<< "\n*****************************\n\n" << desc << std::endl;
return 1;
}
if (vm.count("hidden"))
{
std::cout << allDescriptions << std::endl;
@@ -114,10 +123,12 @@ bool process_command_line(int argc, char** argv)
if(vm.count("testLicense"))
{
keygen.encodeLicense(user,days);
keygen.printLicenseAndWriteItToFile();
}
else
{
keygen.encodeLicense(user,type,seats);
keygen.printLicenseAndWriteItToFile();
}
}
+43
View File
@@ -51,6 +51,49 @@ public:
TS_ASSERT_EQUALS(license.getSeats(), 20);
}
void test_create_test_license_and_validate()
{
Generator generator("v2");
generator.generateKeys();
generator.loadPrivateKeyFromString(generator.getPrivateKeyPEMFileAsString());
License license;
license.loadPublicKeyFromString(generator.getPublicKeyPEMFileAsString());
license.loadFromString(generator.encodeLicense("User", 10));
TS_ASSERT(license.isValid());
TS_ASSERT_EQUALS(license.getTimeLeft(), 10);
license.loadPublicKeyFromString(generator.getPublicKeyPEMFileAsString());
license.loadFromString(generator.encodeLicense("User", -10));
TS_ASSERT(!license.isValid());
// -1 and not -10 since it means it is expired
TS_ASSERT_EQUALS(license.getTimeLeft(), -1);
}
void test_create_licenses_and_check_the_license_info()
{
Generator generator("v2");
generator.generateKeys();
generator.loadPrivateKeyFromString(generator.getPrivateKeyPEMFileAsString());
License license;
license.loadPublicKeyFromString(generator.getPublicKeyPEMFileAsString());
license.create("TestUser", "v2", generator.getPrivateKey());
std::string testInfo = "TestUser\nPrivate License\n1 Seat";
TS_ASSERT_EQUALS(license.getLicenseInfo(), testInfo);
license.create("TestUser", "v2", generator.getPrivateKey(), "Volume License", 20);
testInfo = "TestUser\nVolume License\n20 Seats";
TS_ASSERT_EQUALS(license.getLicenseInfo(), testInfo);
license.create("TestUser", "v2", generator.getPrivateKey(), "Private/Academic Single User License", 20);
testInfo = "TestUser\nPrivate/Academic Single User License\nnot registered for commercial development";
TS_ASSERT_EQUALS(license.getLicenseInfo(), testInfo);
}
void test_create_license_and_validate()
{
Generator generator("v2");