From f2e4ad16617b2440cad26eef9a428ffdb5385038 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Tue, 27 Feb 2018 16:55:11 +0100 Subject: [PATCH] logic: Changed seats to users in license generator and license check --- CMakeLists.txt | 3 +- src/lib/CMakeLists.txt | 2 - src/lib/LicenseChecker.cpp | 3 + src/lib_license/License.cpp | 88 ++-- src/lib_license/License.h | 9 +- src/lib_utility/CMakeLists.txt | 3 + src/lib_utility/utility/utilityString.cpp | 477 ++++++++++++++++++++++ src/lib_utility/utility/utilityString.h | 206 ++++++++++ src/license_generator/Generator.cpp | 10 +- src/license_generator/Generator.h | 4 +- src/license_generator/main.cpp | 28 +- src/test/GeneratorTestSuite.h | 6 +- 12 files changed, 768 insertions(+), 71 deletions(-) create mode 100644 src/lib_utility/utility/utilityString.cpp create mode 100644 src/lib_utility/utility/utilityString.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f8232cc7..cb09d62e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,6 +252,7 @@ create_source_groups(${LIB_LICENSE_FILES}) target_include_directories( ${LIB_LICENSE_PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/src/lib_license" "${CMAKE_BINARY_DIR}/src/lib_license" + "${CMAKE_SOURCE_DIR}/src/lib_utility" ) target_include_directories(${LIB_LICENSE_PROJECT_NAME} SYSTEM @@ -684,7 +685,7 @@ if(UNIX AND NOT APPLE) set_target_properties(${LICENSE_GENERATOR_PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "-pthread") endif() -target_link_libraries(${LICENSE_GENERATOR_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME} ${Boost_LIBRARIES} ) +target_link_libraries(${LICENSE_GENERATOR_PROJECT_NAME} ${LIB_UTILITY_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME} ${Boost_LIBRARIES} ) # CxxTest ---------------------------------------------------------------------- diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 903c7c09..64cbc2e3 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -540,8 +540,6 @@ add_files( utility/utilityLibrary.h utility/utilityMath.cpp utility/utilityMath.h - utility/utilityString.cpp - utility/utilityString.h utility/utilityUuid.cpp utility/utilityUuid.h utility/utilityXml.cpp diff --git a/src/lib/LicenseChecker.cpp b/src/lib/LicenseChecker.cpp index 0e68c83a..6f5cb58d 100644 --- a/src/lib/LicenseChecker.cpp +++ b/src/lib/LicenseChecker.cpp @@ -79,11 +79,13 @@ LicenseChecker::LicenseState LicenseChecker::checkCurrentLicense() const std::string licenseString = appSettings->getLicenseString(); if (licenseString.size() == 0) { + LOG_ERROR_STREAM(<< "No license key available."); return LICENSE_EMPTY; } if (!License::checkLocation(appPath.getAbsolute().str(), appSettings->getLicenseCheck())) { + LOG_ERROR_STREAM(<< "Application was moved, reenter license key."); return LICENSE_MOVED; } @@ -91,6 +93,7 @@ LicenseChecker::LicenseState LicenseChecker::checkCurrentLicense() const bool isLoaded = license.loadFromEncodedString(licenseString, appPath.str()); if (!isLoaded) { + LOG_ERROR_STREAM(<< "License is invalid or application was moved."); return LICENSE_MOVED; } diff --git a/src/lib_license/License.cpp b/src/lib_license/License.cpp index bbb499bd..5e221ee5 100644 --- a/src/lib_license/License.cpp +++ b/src/lib_license/License.cpp @@ -21,24 +21,16 @@ #include "botan/auto_rng.h" #include "botan/pbkdf.h" +#include "utility/utilityString.h" #include "utility/Version.h" #include "PublicKey.h" -namespace -{ - std::string trimWhiteSpaces(const std::string &str) - { - auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c){ return std::isspace(c); }); - auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c){ return std::isspace(c); }).base(); - return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback)); - } -} - License::License() : m_rng(std::make_shared()) , m_user("") , m_type("Private License") - , m_seats(0) + , m_numberOfUsers(0) + , m_createdWithSeats(false) , m_expire("") { loadPublicKey(); @@ -52,7 +44,7 @@ void License::createHeader( const std::string& user, const std::string& type, const std::string& expiration, - unsigned int seats + size_t numberOfUsers ) { if (user.empty() || type.empty() || expiration.empty()) @@ -62,7 +54,7 @@ void License::createHeader( m_user = user; m_expire = expiration; m_type = type; - m_seats = seats; + m_numberOfUsers = numberOfUsers; } std::string License::getMessage(bool withNewlines) const @@ -78,17 +70,17 @@ std::string License::getMessage(bool withNewlines) const message += LicenseConstants::PRODUCT_STRING + separator; message += LicenseConstants::LICENSED_TO_STRING + m_user + separator; message += LicenseConstants::LICENSE_TYPE_STRING + m_type; - if (m_seats > 1) + if (m_numberOfUsers > 1) { - message += " (" + std::to_string(m_seats) + " Seats)"; + message += " (" + std::to_string(m_numberOfUsers) + (m_createdWithSeats ? " Seats)" : " users)"); } - else if (m_seats == 1) + else if (m_numberOfUsers == 1) { - message += " (1 Seat)"; + message += (m_createdWithSeats ? " (1 Seat)" : " (1 user)"); } else if (m_type == LicenseConstants::TEST_LICENSE_STRING) { - message += " (unlimited seats)"; + message += (m_createdWithSeats ? " (unlimited seats)" : " (unlimited users)"); } message += separator; message += getExpireLine() + separator; @@ -103,7 +95,7 @@ std::string License::getLine(std::istream& stream) std::string line; if(getline(stream, line, '\n')) { - return trimWhiteSpaces(line); + return utility::trim(line); } return ""; } @@ -140,7 +132,7 @@ bool License::extractData(const std::string& data, LICENSE_LINE line) } return !m_expire.empty(); case TYPE_LINE: - setTypeAndSeats(removeCaption(data, LicenseConstants::LICENSE_TYPE_STRING)); + setTypeAndNumberOfUsers(removeCaption(data, LicenseConstants::LICENSE_TYPE_STRING)); return !m_type.empty(); default: return false; @@ -164,9 +156,9 @@ bool License::isNonCommercialLicenseType() const return false; } -unsigned int License::getSeats() const +size_t License::getNumberOfUsers() const { - return m_seats; + return m_numberOfUsers; } std::string License::getType() const @@ -196,15 +188,15 @@ std::string License::getLicenseInfo() const } else if (m_type == LicenseConstants::TEST_LICENSE_STRING) { - info += "unlimited Seats"; + info += "unlimited users"; } - else if (m_seats > 1) + else if (m_numberOfUsers > 1) { - info += std::to_string(m_seats) + " Seats"; + info += std::to_string(m_numberOfUsers) + " users"; } else { - info += "1 Seat"; + info += "1 user"; } return info; @@ -282,7 +274,7 @@ bool License::load(std::istream& stream) // separator line getline(stream, line, '\n'); - if (trimWhiteSpaces(line) != LicenseConstants::SEPARATOR_STRING) + if (utility::trim(line) != LicenseConstants::SEPARATOR_STRING) { return false; } @@ -294,7 +286,7 @@ bool License::load(std::istream& stream) m_signature = ""; while (getline(stream, line, '\n')) { - std::string l = trimWhiteSpaces(line); + std::string l = utility::trim(line); if (l == LicenseConstants::END_LICENSE_STRING) { break; @@ -312,26 +304,31 @@ bool License::load(std::istream& stream) return true; } -void License::setTypeAndSeats(const std::string& line) +void License::setTypeAndNumberOfUsers(const std::string& line) { size_t pos = line.find("("); - if ( pos != line.npos) + if (pos != line.npos) { m_type = line.substr(0, pos - 1); try { - m_seats = std::stoi(line.substr(pos+1)); + m_numberOfUsers = std::stoi(line.substr(pos+1)); } catch (std::invalid_argument e) { - m_seats = 0; + m_numberOfUsers = 0; + } + + if (utility::toLowerCase(line).find("seat") != line.npos) + { + m_createdWithSeats = true; } } else { m_type = line; - m_seats = 0; + m_numberOfUsers = 0; } } @@ -348,7 +345,7 @@ void License::print() bool License::isValid() const { - if(!m_publicKey) + if (!m_publicKey) { std::cout << "No public key loaded" << std::endl; return false; @@ -369,6 +366,12 @@ bool License::isValid() const return false; } + if (isExpired()) + { + std::cout << "License is expired" << std::endl; + return false; + } + Botan::PK_Verifier verifier(*m_publicKey.get(), "EMSA4(SHA-256)"); Botan::DataSource_Memory in(getMessage()); @@ -379,8 +382,9 @@ bool License::isValid() const } const bool ok = verifier.check_signature(signature); - if (isExpired()) + if (!ok) { + std::cout << "License check failed" << std::endl; return false; } return ok; @@ -394,9 +398,9 @@ bool License::isValid() const bool License::isExpired() const { - if ( getType() == LicenseConstants::TEST_LICENSE_STRING) + if (getType() == LicenseConstants::TEST_LICENSE_STRING) { - return (getTimeLeft()==-1); + return (getTimeLeft() == -1); } else { @@ -407,7 +411,7 @@ bool License::isExpired() const std::string License::getPublicKeyFilename() const { - if(m_publicKeyFilename.empty()) + if (m_publicKeyFilename.empty()) { return "public-sourcetrail" + KEY_FILEENDING; } @@ -421,9 +425,10 @@ bool License::loadPublicKeyFromFile(const std::string& filename) m_publicKeyFilename = filename; } - if(boost::filesystem::exists(getPublicKeyFilename())) + if (boost::filesystem::exists(getPublicKeyFilename())) { - Botan::RSA_PublicKey* rsaPublicKey = dynamic_cast(Botan::X509::load_key(getPublicKeyFilename())); + Botan::RSA_PublicKey* rsaPublicKey = + dynamic_cast(Botan::X509::load_key(getPublicKeyFilename())); if (!rsaPublicKey) { @@ -535,7 +540,8 @@ std::string License::getLicenseEncodedString(const std::string& applicationLocat return ""; } - std::string result = Botan::CryptoBox::encrypt(&fileContents[0], fileContents.size(), getEncodeKey(applicationLocation), rng); + std::string result = + Botan::CryptoBox::encrypt(&fileContents[0], fileContents.size(), getEncodeKey(applicationLocation), rng); //remove Botan Cryptobox begin and end //should not be in the application settings diff --git a/src/lib_license/License.h b/src/lib_license/License.h index a9d3bdf8..feca55b4 100644 --- a/src/lib_license/License.h +++ b/src/lib_license/License.h @@ -55,20 +55,20 @@ public: void setLine(const LICENSE_LINE line, const std::string& value); void setHashLine(const std::string& hash); - void setTypeAndSeats(const std::string& line); + void setTypeAndNumberOfUsers(const std::string& line); std::string getLicenseInfo() const; std::string getPublicKeyFilename() const; std::string getVersion() const; std::string getType() const; std::string getUser() const; - unsigned int getSeats() const; + size_t getNumberOfUsers() const; void createHeader( const std::string& user, const std::string& type, const std::string& expiration, - unsigned int seats = 0 + size_t numberOfUsers = 0 ); std::string getExpireLine() const; @@ -115,7 +115,8 @@ private: // message std::string m_user; std::string m_type; - unsigned int m_seats; + size_t m_numberOfUsers; + bool m_createdWithSeats; std::string m_expire; std::string m_hashLine; diff --git a/src/lib_utility/CMakeLists.txt b/src/lib_utility/CMakeLists.txt index 27381730..4ec9252d 100644 --- a/src/lib_utility/CMakeLists.txt +++ b/src/lib_utility/CMakeLists.txt @@ -4,4 +4,7 @@ add_files( utility/TextCodec.cpp utility/TextCodec.h + + utility/utilityString.cpp + utility/utilityString.h ) diff --git a/src/lib_utility/utility/utilityString.cpp b/src/lib_utility/utility/utilityString.cpp new file mode 100644 index 00000000..c003225f --- /dev/null +++ b/src/lib_utility/utility/utilityString.cpp @@ -0,0 +1,477 @@ +#include "utility/utilityString.h" + +#include +#include +#include +#include + +#include + +namespace +{ + template + StringType doReplace(StringType str, const StringType& from, const StringType& to) + { + size_t pos = 0; + + if (from.size() == 0) + { + return str; + } + + while ((pos = str.find(from, pos)) != std::string::npos) + { + str.replace(pos, from.length(), to); + pos += to.length(); + } + + return str; + } + + template + StringType doReplaceBetween(const StringType& str, typename StringType::value_type startDelimiter, typename StringType::value_type endDelimiter, const StringType& to) + { + size_t startPos = str.find(startDelimiter); + if (startPos == StringType::npos) + { + return str; + } + + size_t depth = 1; + + for (size_t pos = startPos + 1; pos < str.size(); pos++) + { + if (str[pos] == endDelimiter && depth) + { + depth--; + + if (depth == 0) + { + StringType end = doReplaceBetween(str.substr(pos + 1), startDelimiter, endDelimiter, to); + return str.substr(0, startPos) + startDelimiter + to + endDelimiter + end; + } + } + + if (str[pos] == startDelimiter) + { + depth++; + } + } + + return str; + } +} + +namespace utility +{ + std::string encodeToUtf8(const std::wstring& s) + { + return boost::locale::conv::utf_to_utf(s.c_str(), s.c_str() + s.size()); + } + + std::wstring decodeFromUtf8(const std::string& s) + { + return boost::locale::conv::utf_to_utf(s.c_str(), s.c_str() + s.size()); + } + + std::deque split(const std::string& str, char delimiter) + { + return split>(str, std::string(1, delimiter)); + } + + std::deque split(const std::string& str, const std::string& delimiter) + { + return split>(str, delimiter); + } + + std::vector splitToVector(const std::string& str, char delimiter) + { + return split>(str, std::string(1, delimiter)); + } + + std::vector splitToVector(const std::string& str, const std::string& delimiter) + { + return split>(str, delimiter); + } + + std::vector splitToVector(const std::wstring& str, wchar_t delimiter) + { + return split>(str, std::wstring(1, delimiter)); + } + + std::vector splitToVector(const std::wstring& str, const std::wstring& delimiter) + { + return split>(str, delimiter); + } + + std::string join(const std::deque& list, char delimiter) + { + return join >(list, std::string(1, delimiter)); + } + + std::string join(const std::deque& list, const std::string& delimiter) + { + return join >(list, delimiter); + } + + std::string join(const std::vector& list, char delimiter) + { + return join >(list, std::string(1, delimiter)); + } + + std::string join(const std::vector& list, const std::string& delimiter) + { + return join >(list, delimiter); + } + + std::deque tokenize(const std::string& str, char delimiter) + { + return tokenize(str, std::string(1, delimiter)); + } + + std::deque tokenize(const std::string& str, const std::string& delimiter) + { + size_t pos = 0; + size_t oldPos = 0; + std::deque c; + + do + { + pos = str.find(delimiter, oldPos); + + if (pos != oldPos) + { + c.push_back(str.substr(oldPos, pos - oldPos)); + } + + if (pos != std::string::npos) + { + c.push_back(str.substr(pos, delimiter.size())); + } + + oldPos = pos + delimiter.size(); + } + while (pos != std::string::npos && oldPos < str.size()); + + return c; + } + + std::deque tokenize(const std::deque& list, char delimiter) + { + return tokenize(list, std::string(1, delimiter)); + } + + std::deque tokenize(const std::deque& list, const std::string& delimiter) + { + std::deque c; + + for (const std::string& str : list) + { + if (str.size()) + { + std::deque c2 = tokenize(str, delimiter); + c.insert(c.end(), c2.begin(), c2.end()); + } + } + + return c; + } + + std::string substrBeforeFirst(const std::string& str, char delimiter) + { + size_t pos = str.find(delimiter); + if (pos != std::string::npos) + { + return str.substr(0, pos); + } + return str; + } + + std::string substrBeforeFirst(const std::string& str, const std::string& delimiter) + { + size_t pos = str.find(delimiter); + if (pos != std::string::npos) + { + return str.substr(0, pos); + } + return str; + } + + std::string substrBeforeLast(const std::string& str, char delimiter) + { + size_t pos = str.rfind(delimiter); + if (pos != std::string::npos) + { + return str.substr(0, pos); + } + return str; + } + + std::wstring substrBeforeLast(const std::wstring& str, wchar_t delimiter) + { + size_t pos = str.rfind(delimiter); + if (pos != std::wstring::npos) + { + return str.substr(0, pos); + } + return str; + } + + std::string substrAfter(const std::string& str, char delimiter) + { + size_t pos = str.find(delimiter); + if (pos != std::string::npos) + { + return str.substr(pos + 1, str.size()); + } + return str; + } + + std::string substrAfter(const std::string& str, const std::string& delimiter) + { + size_t pos = str.find(delimiter); + if (pos != std::string::npos) + { + return str.substr(pos + delimiter.size(), str.size()); + } + return str; + } + + std::string toUpperCase(const std::string& in) + { + std::string out; + std::transform(in.begin(), in.end(), std::back_inserter(out), toupper); + return out; + } + + std::string toLowerCase(const std::string& in) + { + std::string out; + std::transform(in.begin(), in.end(), std::back_inserter(out), tolower); + return out; + } + + std::wstring toLowerCase(const std::wstring& in) + { + std::wstring out; + std::transform(in.begin(), in.end(), std::back_inserter(out), tolower); + return out; + } + + std::string replace(std::string str, const std::string& from, const std::string& to) + { + return doReplace(str, from, to); + } + + std::wstring replace(std::wstring str, const std::wstring& from, const std::wstring& to) + { + return doReplace(str, from, to); + } + + std::string replaceBetween(const std::string& str, char startDelimiter, char endDelimiter, const std::string& to) + { + return doReplaceBetween(str, startDelimiter, endDelimiter, to); + } + + std::wstring replaceBetween(const std::wstring& str, wchar_t startDelimiter, wchar_t endDelimiter, const std::wstring& to) + { + return doReplaceBetween(str, startDelimiter, endDelimiter, to); + } + + std::string insertLineBreaksAtBlankSpaces(const std::string& s, size_t maxLineLength) + { + const std::vector atoms = splitToVector(s, " "); + + std::string ret = ""; + std::string currentLine = ""; + for (const std::string& atom: atoms) + { + if (currentLine.size() + 1 + atom.size() <= maxLineLength) + { + currentLine += " " + atom; + } + else + { + if (!ret.empty()) + { + ret += "\n"; + } + + if (currentLine.empty()) + { + ret += atom; + } + else + { + ret += currentLine; + currentLine = atom; + } + } + } + if (!currentLine.empty()) + { + if (!ret.empty()) + { + ret += "\n"; + } + ret += currentLine; + } + return ret; + } + + std::string breakSignature( + std::string returnPart, std::string namePart, std::string paramPart, + size_t maxLineLength, size_t tabWidth) + { + namePart = ' ' + namePart; + + size_t totalSize = returnPart.size() + namePart.size() + paramPart.size(); + if (totalSize <= maxLineLength) + { + return returnPart + namePart + paramPart; + } + + if (paramPart.size()) + { + namePart += paramPart[0]; + paramPart.erase(0, 1); + } + + size_t parenPos = paramPart.rfind(')'); + std::string endPart; + if (parenPos == 0) + { + namePart += paramPart; + paramPart = ""; + } + else if (parenPos != std::string::npos) + { + endPart = paramPart.substr(parenPos); + paramPart = paramPart.substr(0, parenPos); + } + + if (paramPart.size() && paramPart.size() + tabWidth - endPart.size() > maxLineLength) + { + std::vector paramLines; + while (true) + { + size_t parenCount = 0; + bool split = false; + for (size_t i = 0; i < paramPart.size(); i++) + { + char c = paramPart[i]; + if (parenCount == 0 && c == ',') + { + paramLines.push_back(paramPart.substr(0, i + 1)); + paramPart = paramPart.substr(i + 2); + split = true; + break; + } + else if (c == '<' || c == '(') + { + parenCount++; + } + else if (c == '>' || c == ')') + { + parenCount--; + } + } + + if (!split) + { + paramLines.push_back(paramPart); + break; + } + } + + paramPart = ""; + for (const std::string& str : paramLines) + { + paramPart += "\n\t" + str; + size_t length = tabWidth + str.size(); + maxLineLength = std::max(length, maxLineLength); + } + } + else if (paramPart.size()) + { + paramPart = "\n\t" + paramPart; + } + + if (returnPart.size() + namePart.size() <= maxLineLength) + { + namePart = returnPart + namePart; + returnPart = ""; + } + + std::string sig; + + if (returnPart.size()) + { + sig += returnPart + '\n'; + } + + sig += namePart; + + if (paramPart.size()) + { + sig += paramPart; + } + + if (endPart.size()) + { + sig += '\n' + endPart; + } + + return sig; + } + + std::string trim(const std::string &str) + { + auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c) { return std::isspace(c); }); + auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c) { return std::isspace(c); }).base(); + return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback)); + } + + std::wstring trim(const std::wstring &str) + { + auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c) { return std::isspace(c); }); + auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c) { return std::isspace(c); }).base(); + return (wsback <= wsfront ? std::wstring() : std::wstring(wsfront, wsback)); + } + + std::string elide(const std::string& str, ElideMode mode, size_t size) + { + if (str.size() <= size || str.size() <= 3) + { + return str; + } + + switch (mode) + { + case ELIDE_LEFT: + return "..." + str.substr(str.size() - size - 3, str.size()); + case ELIDE_MIDDLE: + return str.substr(0, size / 2 - 1) + "..." + str.substr(str.size() - (size / 2 - 2), str.size()); + case ELIDE_RIGHT: + return str.substr(0, size - 3) + "..."; + } + } + + std::wstring elide(const std::wstring& str, ElideMode mode, size_t size) + { + if (str.size() <= size || str.size() <= 3) + { + return str; + } + + switch (mode) + { + case ELIDE_LEFT: + return L"..." + str.substr(str.size() - size - 3, str.size()); + case ELIDE_MIDDLE: + return str.substr(0, size / 2 - 1) + L"..." + str.substr(str.size() - (size / 2 - 2), str.size()); + case ELIDE_RIGHT: + return str.substr(0, size - 3) + L"..."; + } + } +} diff --git a/src/lib_utility/utility/utilityString.h b/src/lib_utility/utility/utilityString.h new file mode 100644 index 00000000..7cfa954e --- /dev/null +++ b/src/lib_utility/utility/utilityString.h @@ -0,0 +1,206 @@ +#ifndef UTILITY_STRING_H +#define UTILITY_STRING_H + +#include +#include +#include +#include + +namespace utility +{ + std::string encodeToUtf8(const std::wstring& s); + std::wstring decodeFromUtf8(const std::string& s); + + template + ContainerType split(const std::string& str, const std::string& delimiter); + + template + ContainerType split(const std::wstring& str, const std::wstring& delimiter); + + std::deque split(const std::string& str, char delimiter); + std::deque split(const std::string& str, const std::string& delimiter); + std::vector splitToVector(const std::string& str, char delimiter); + std::vector splitToVector(const std::string& str, const std::string& delimiter); + std::vector splitToVector(const std::wstring& str, wchar_t delimiter); + std::vector splitToVector(const std::wstring& str, const std::wstring& delimiter); + + template + std::string join(const ContainerType& list, const std::string& delimiter); + + template + std::wstring join(const ContainerType& list, const std::wstring& delimiter); + + std::string join(const std::deque& list, char delimiter); + std::string join(const std::deque& list, const std::string& delimiter); + std::string join(const std::vector& list, char delimiter); + std::string join(const std::vector& list, const std::string& delimiter); + + std::deque tokenize(const std::string& str, char delimiter); + std::deque tokenize(const std::string& str, const std::string& delimiter); + std::deque tokenize(const std::deque& list, char delimiter); + std::deque tokenize(const std::deque& list, const std::string& delimiter); + + std::string substrBeforeFirst(const std::string& str, char delimiter); + std::string substrBeforeFirst(const std::string& str, const std::string& delimiter); + std::string substrBeforeLast(const std::string& str, char delimiter); + std::wstring substrBeforeLast(const std::wstring& str, wchar_t delimiter); + std::string substrAfter(const std::string& str, char delimiter); + std::string substrAfter(const std::string& str, const std::string& delimiter); + + template + StringType substrBetween(const StringType& str, const StringType& delimiter1, const StringType& delimiter2); + + template + bool isPrefix(const StringType& prefix, const StringType& text); + + template + bool isPostfix(const StringType& postfix, const StringType& text); + + std::string toUpperCase(const std::string& in); + std::string toLowerCase(const std::string& in); + std::wstring toLowerCase(const std::wstring& in); + + template + bool equalsCaseInsensitive(const std::string& a, const std::string& b); + + std::string replace(std::string str, const std::string& from, const std::string& to); + std::wstring replace(std::wstring str, const std::wstring& from, const std::wstring& to); + + std::string replaceBetween(const std::string& str, char startDelimiter, char endDelimiter, const std::string& to); + std::wstring replaceBetween(const std::wstring& str, wchar_t startDelimiter, wchar_t endDelimiter, const std::wstring& to); + + std::string insertLineBreaksAtBlankSpaces(const std::string& s, size_t maxLineLength); + std::string breakSignature( + std::string returnPart, std::string namePart, std::string paramPart, + size_t maxLineLength, size_t tabWidth); + + std::string trim(const std::string &str); + std::wstring trim(const std::wstring &str); + + enum ElideMode + { + ELIDE_LEFT, + ELIDE_MIDDLE, + ELIDE_RIGHT + }; + + std::string elide(const std::string& str, ElideMode mode, size_t size); + std::wstring elide(const std::wstring& str, ElideMode mode, size_t size); + + template + ContainerType split(const std::string& str, const std::string& delimiter) + { + size_t pos = 0; + size_t oldPos = 0; + ContainerType c; + + do + { + pos = str.find(delimiter, oldPos); + c.push_back(str.substr(oldPos, pos - oldPos)); + oldPos = pos + delimiter.size(); + } while (pos != std::string::npos); + + return c; + } + + template + ContainerType split(const std::wstring& str, const std::wstring& delimiter) + { + size_t pos = 0; + size_t oldPos = 0; + ContainerType c; + + do + { + pos = str.find(delimiter, oldPos); + c.push_back(str.substr(oldPos, pos - oldPos)); + oldPos = pos + delimiter.size(); + } while (pos != std::wstring::npos); + + return c; + } + + template + std::string join(const ContainerType& list, const std::string& delimiter) + { + std::stringstream ss; + bool first = true; + for (const std::string& str : list) + { + if (!first) + { + ss << delimiter; + } + first = false; + + ss << str; + } + return ss.str(); + } + + + template + std::wstring join(const ContainerType& list, const std::wstring& delimiter) + { + std::wstringstream ss; + bool first = true; + for (const std::wstring& str : list) + { + if (!first) + { + ss << delimiter; + } + first = false; + + ss << str; + } + return ss.str(); + } + + + template + StringType substrBetween(const StringType& str, const StringType& delimiter1, const StringType& delimiter2) + { + size_t found_delimiter1 = str.find(delimiter1); + found_delimiter1 += delimiter1.length(); + size_t found_delimiter2 = str.find(delimiter2, found_delimiter1); + if (found_delimiter1 != str.npos && found_delimiter2 != str.npos) + { + return str.substr(found_delimiter1, found_delimiter2 - found_delimiter1); + } + return StringType(); + } + + + template + bool isPrefix(const StringType& prefix, const StringType& text) + { + if (prefix.size() <= text.size()) + { + std::pair res = + std::mismatch(prefix.begin(), prefix.end(), text.begin()); + + return res.first == prefix.end(); + } + return false; + } + + template + bool isPostfix(const StringType& postfix, const StringType& text) + { + return text.size() >= postfix.size() && text.rfind(postfix) == (text.size() - postfix.size()); + } + + template + bool equalsCaseInsensitive(const StringType& a, const StringType& b) + { + if (a.size() == b.size()) + { + return toLowerCase(a) == toLowerCase(b); + } + return false; + } +} + +#endif // UTILITY_STRING_H diff --git a/src/license_generator/Generator.cpp b/src/license_generator/Generator.cpp index 612c7eb0..1bca54ef 100644 --- a/src/license_generator/Generator.cpp +++ b/src/license_generator/Generator.cpp @@ -71,7 +71,7 @@ std::string Generator::encodeLicense(const std::string& user, const int days) std::string Generator::encodeLicense( const std::string& user, const std::string& licenseType, - const int seats, + size_t numberOfUsers, const std::string& version ) { @@ -93,13 +93,13 @@ std::string Generator::encodeLicense( Version tempVersion = Version::fromString(version); if (tempVersion.isValid()) { - createLicense(user, licenseType, tempVersion.toShortString(), seats); + createLicense(user, licenseType, tempVersion.toShortString(), numberOfUsers); } } if (!m_license) { - createLicense(user, licenseType, getExpireVersion(), seats); + createLicense(user, licenseType, getExpireVersion(), numberOfUsers); } @@ -240,12 +240,12 @@ void Generator::createLicense( const std::string& user, const std::string& type, const std::string& expiration, - const unsigned int seats + size_t numberOfUsers ) { m_license = std::make_unique(); - m_license->createHeader(user, type, expiration, seats); + m_license->createHeader(user, type, expiration, numberOfUsers); Botan::AutoSeeded_RNG rng; std::string pass9 = Botan::generate_passhash9(m_license->getExpireLine(), m_rng); diff --git a/src/license_generator/Generator.h b/src/license_generator/Generator.h index 8fe44a26..35b0fa4d 100644 --- a/src/license_generator/Generator.h +++ b/src/license_generator/Generator.h @@ -21,7 +21,7 @@ public: std::string encodeLicense( const std::string& user, const std::string& licenseType, - const int seats = 0, + size_t numberOfUsers = 0, const std::string& version = "" ); std::string encodeLicense( @@ -45,7 +45,7 @@ public: const std::string& user, const std::string& type, const std::string& expiration, - const unsigned int seates + size_t numberOfUsers ); std::string getExpireVersion(int versions = 4); diff --git a/src/license_generator/main.cpp b/src/license_generator/main.cpp index 12e8a7a3..235cf734 100644 --- a/src/license_generator/main.cpp +++ b/src/license_generator/main.cpp @@ -22,7 +22,7 @@ bool process_command_line(int argc, char** argv) std::string licenseFile = ""; std::string type = ""; int days = 0; - int seats = 0; + int numberOfUsers = 0; po::options_description modes_description("Sourcetrail Generator Modes"); modes_description.add_options() @@ -33,7 +33,8 @@ bool process_command_line(int argc, char** argv) po::options_description keygen_description("Options Keygeneration"); keygen_description.add_options() ("version,v", po::value(&version), "Versionnumber (in format 20xx.x) until Sourcetrail valid") - ("seats,s", po::value(&seats), "Generate a License, USERNAME as value") + ("users,u", po::value(&numberOfUsers), "Number of users") + ("seats,s", po::value(&numberOfUsers), "Number of users (prev. seats)") ("licenseType,t", po::value(&type), "License Type of ") ("testLicense,e", po::value(&days), "Generates a test license for days"); @@ -83,12 +84,12 @@ bool process_command_line(int argc, char** argv) Generator keygen; - // make sure there are no negative amount of seats - if (vm.count("seats")) + // make sure there are no negative amount of users + if (vm.count("users") || vm.count("seats")) { - if (seats < 0) + if (numberOfUsers < 0) { - std::cout << "Invalid amount of seats. (Must be > 0)" << std::endl; + std::cout << "Invalid amount of users. (Must be > 0)" << std::endl; return false; } } @@ -113,23 +114,23 @@ bool process_command_line(int argc, char** argv) keygen.loadPrivateKeyFromString(PRIVATE_KEY); } - if(vm.count("generate")) + if (vm.count("generate")) { - if(vm.count("testLicense")) + if (vm.count("testLicense")) { - keygen.encodeLicense(user,days); + keygen.encodeLicense(user, days); keygen.printLicenseAndWriteItToFile(); } else { - keygen.encodeLicense(user,type,seats,version); + keygen.encodeLicense(user, type, numberOfUsers, version); keygen.printLicenseAndWriteItToFile(); } } - if(vm.count("check")) + if (vm.count("check")) { - if(keygen.verifyLicense()) + if (keygen.verifyLicense()) { std::cout << "License valid" << std::endl; } @@ -139,11 +140,12 @@ bool process_command_line(int argc, char** argv) } } } - catch(std::exception& e) + catch (std::exception& e) { std::cout << "Exception caught: " << e.what() << std::endl; return false; } + return true; } diff --git a/src/test/GeneratorTestSuite.h b/src/test/GeneratorTestSuite.h index e83e153a..89dbbe5c 100644 --- a/src/test/GeneratorTestSuite.h +++ b/src/test/GeneratorTestSuite.h @@ -48,7 +48,7 @@ public: License license; license.loadFromString(generator.encodeLicense("TestUser", "VolumeLicense", 20)); - TS_ASSERT_EQUALS(license.getSeats(), 20); + TS_ASSERT_EQUALS(license.getNumberOfUsers(), 20); } void test_create_test_license_and_validate() @@ -80,11 +80,11 @@ public: License license; license.loadFromString(generator.encodeLicense("TestUser", "Private License", 1, "2017.4")); - std::string testInfo = "TestUser\nPrivate License\nValid up to version: 2017.4\n1 Seat"; + std::string testInfo = "TestUser\nPrivate License\nValid up to version: 2017.4\n1 user"; TS_ASSERT_EQUALS(license.getLicenseInfo(), testInfo); license.loadFromString(generator.encodeLicense("TestUser", "Volume License", 20, "2017.3")); - testInfo = "TestUser\nVolume License\nValid up to version: 2017.3\n20 Seats"; + testInfo = "TestUser\nVolume License\nValid up to version: 2017.3\n20 users"; TS_ASSERT_EQUALS(license.getLicenseInfo(), testInfo); license.loadFromString(generator.encodeLicense("TestUser", "Private/Academic Single User License", 0, "2018.1"));