Add GoogleTest via conan and first tests

This commit is contained in:
Dario 2020-06-02 12:54:55 +02:00
parent 1aeb506cd3
commit 7518832bf4
15 changed files with 278 additions and 86 deletions

View File

@ -36,6 +36,7 @@ FILE(GLOB PROTO_HEDERA "src/cpp/proto/hedera/*.cc" "src/cpp/proto/hedera/*.h")
# used only for test project # used only for test project
FILE(GLOB TEST "src/cpp/test/*.cpp" "src/cpp/test/*.h") FILE(GLOB TEST "src/cpp/test/*.cpp" "src/cpp/test/*.h")
FILE(GLOB TEST_CRYPTO "src/cpp/test/crypto/*.cpp" "src/cpp/test/crypto/*.h")
SET(LOCAL_SRCS SET(LOCAL_SRCS
${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} ${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface}
@ -61,6 +62,7 @@ source_group("SingletonManager" FILES ${SINGLETON_MANAGER})
source_group("lib" FILES ${LIB_SRC}) source_group("lib" FILES ${LIB_SRC})
source_group("HTTP-Interface" FILES ${HTTPInterface}) source_group("HTTP-Interface" FILES ${HTTPInterface})
source_group("Json-Interface" FILES ${JSONInterface}) source_group("Json-Interface" FILES ${JSONInterface})
source_group("Test\\crypto" FILES ${TEST_CRYPTO})
source_group("Test" FILES ${TEST}) source_group("Test" FILES ${TEST})
endif(MSVC) endif(MSVC)
@ -150,7 +152,7 @@ enable_testing()
#_TEST_BUILD #_TEST_BUILD
add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${TEST}) add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${TEST} ${TEST_CRYPTO})
target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD")
target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ${IROHA_ED25519}) target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ${IROHA_ED25519})
@ -161,3 +163,5 @@ if(WIN32)
else(WIN32) else(WIN32)
target_link_libraries(Gradido_LoginServer_Test libmariadb PocoNet PocoUtil PocoJSON PocoFoundation PocoData PocoNetSSL protoc protobuf -pthread) target_link_libraries(Gradido_LoginServer_Test libmariadb PocoNet PocoUtil PocoJSON PocoFoundation PocoData PocoNetSSL protoc protobuf -pthread)
endif(WIN32) endif(WIN32)
add_test(NAME main COMMAND Gradido_LoginServer_Test)

View File

@ -3,6 +3,7 @@ Poco/1.9.4@pocoproject/stable
libsodium/1.0.18@bincrafters/stable libsodium/1.0.18@bincrafters/stable
protobuf/3.9.1@bincrafters/stable protobuf/3.9.1@bincrafters/stable
boost/1.71.0@conan/stable boost/1.71.0@conan/stable
gtest/1.8.1@bincrafters/stable
[generators] [generators]
cmake cmake

View File

@ -8,6 +8,8 @@
#include "Poco/Types.h" #include "Poco/Types.h"
#include "Passphrase.h"
#include "../ServerConfig.h" #include "../ServerConfig.h"
using namespace Poco::Data::Keywords; using namespace Poco::Data::Keywords;
@ -238,75 +240,7 @@ std::string KeyPair::createClearPassphraseFromWordIndices(MemoryBin* word_indice
std::string KeyPair::filterPassphrase(const std::string& passphrase) std::string KeyPair::filterPassphrase(const std::string& passphrase)
{ {
std::string filteredPassphrase; return Passphrase::filter(passphrase);
auto passphrase_size = passphrase.size();
for (int i = 0; i < passphrase_size; i++) {
unsigned char c = passphrase.data()[i];
// asci 128 even by utf8 (hex)
// 0000 0000 0000 007F
// utf8
if (c > 0x0000007F) {
int additionalUtfByteCount = 0;
//filteredPassphrase += c;
if ((c & 0x00000080) == 0x00000080) {
// c3 a4 => ä
// c3 bc => ü
// c3 b6 => ö
// c3 84 => Ä
// c3 96 => Ö
// c3 9c => Ü
// c3 9f => ß
unsigned char c2 = passphrase.data()[i + 1];
bool insertedHtmlEntitie = false;
for (auto it = g_specialChars.begin(); it != g_specialChars.end(); it++) {
if (c2 == it->get<0>()) {
auto htmlEntitie = it->get<1>();
filteredPassphrase += "&";
filteredPassphrase += htmlEntitie;
filteredPassphrase += ";";
i++;
insertedHtmlEntitie = true;
break;
}
}
if (insertedHtmlEntitie) continue;
additionalUtfByteCount = 1;
}
else if ((c & 0x00000800) == 0x00000800) {
additionalUtfByteCount = 2;
}
else if ((c & 0x00010000) == 0x00010000) {
additionalUtfByteCount = 3;
}
for (int j = 0; j <= additionalUtfByteCount; j++) {
filteredPassphrase += passphrase.data()[i + j];
i++;
}
}
else {
// 32 = Space
// 65 = A
// 90 = Z
// 97 = a
// 122 = z
// 59 = ;
// 38 = &
if (c == 32 || c == 59 || c == 38 ||
(c >= 65 && c <= 90) ||
(c >= 97 && c <= 122)) {
filteredPassphrase += c;
}
else if (c == '\n' || c == '\r') {
filteredPassphrase += ' ';
}
}
}
return filteredPassphrase;
} }
std::string KeyPair::getPubkeyHex() std::string KeyPair::getPubkeyHex()

View File

@ -8,8 +8,6 @@
#include "ed25519/ed25519.h" #include "ed25519/ed25519.h"
#include <sodium.h> #include <sodium.h>
class UserWriteKeysIntoDB; class UserWriteKeysIntoDB;
class UserGenerateKeys; class UserGenerateKeys;
class DebugPassphrasePage; class DebugPassphrasePage;

View File

@ -96,8 +96,9 @@ std::string Passphrase::filter(const std::string& passphrase)
return filteredPassphrase; return filteredPassphrase;
} }
Poco::SharedPtr<Passphrase> Passphrase::transform(const Mnemonic* targetWordSource) Poco::AutoPtr<Passphrase> Passphrase::transform(const Mnemonic* targetWordSource)
{ {
/* /*
if (!currentWordSource || !targetWordSource) { if (!currentWordSource || !targetWordSource) {
return ""; return "";
@ -112,16 +113,34 @@ Poco::SharedPtr<Passphrase> Passphrase::transform(const Mnemonic* targetWordSour
return createClearPassphraseFromWordIndices(word_indices, targetWordSource);*/ return createClearPassphraseFromWordIndices(word_indices, targetWordSource);*/
// Poco::SharedPtr<Passphrase> transformedPassphrase = new Passphrase() // Poco::SharedPtr<Passphrase> transformedPassphrase = new Passphrase()
if (!targetWordSource || mWordSource) {
return nullptr;
}
if (targetWordSource == mWordSource) {
return this;
}
if (createWordIndices()) {
return create(mWordIndices, targetWordSource);
}
return nullptr;
} }
Poco::SharedPtr<Passphrase> Passphrase::create(const MemoryBin* wordIndices, const Mnemonic* wordSource) Poco::AutoPtr<Passphrase> Passphrase::create(const MemoryBin* wordIndices, const Mnemonic* wordSource)
{
if (PHRASE_WORD_COUNT * sizeof(Poco::UInt16) >= wordIndices->size()) {
return nullptr;
}
const Poco::UInt16* word_indices_p = (const Poco::UInt16*)wordIndices->data();
return create(word_indices_p, wordSource);
}
Poco::AutoPtr<Passphrase> Passphrase::create(const Poco::UInt16 wordIndices[PHRASE_WORD_COUNT], const Mnemonic* wordSource)
{ {
//Poco::SharedPtr<Passphrase> passphrase = new Passphrase()
const Poco::UInt64* word_indices_p = (const Poco::UInt64*)wordIndices->data();
std::string clearPassphrase; std::string clearPassphrase;
for (int i = 0; i < PHRASE_WORD_COUNT; i++) { for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
if (i * sizeof(Poco::UInt64) >= wordIndices->size()) break; auto word = wordSource->getWord(wordIndices[i]);
auto word = wordSource->getWord(word_indices_p[i]);
if (word) { if (word) {
clearPassphrase += word; clearPassphrase += word;
clearPassphrase += " "; clearPassphrase += " ";

View File

@ -5,16 +5,21 @@
#include "mnemonic.h" #include "mnemonic.h"
#include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/MemoryManager.h"
class Passphrase
#include "../lib/AutoPtrContainer.h"
#include "Poco/AutoPtr.h"
class Passphrase : public AutoPtrContainer
{ {
public: public:
Passphrase(const std::string& passphrase, const Mnemonic* wordSource); Passphrase(const std::string& passphrase, const Mnemonic* wordSource);
static Poco::SharedPtr<Passphrase> create(const MemoryBin* wordIndices, const Mnemonic* wordSource); static Poco::AutoPtr<Passphrase> create(const Poco::UInt16 wordIndices[PHRASE_WORD_COUNT], const Mnemonic* wordSource);
static Poco::AutoPtr<Passphrase> create(const MemoryBin* wordIndices, const Mnemonic* wordSource);
static const Mnemonic* detectMnemonic(const std::string& passphrase, const MemoryBin* publicKey = nullptr); static const Mnemonic* detectMnemonic(const std::string& passphrase, const MemoryBin* publicKey = nullptr);
//! \brief transform passphrase into another language/mnemonic source //! \brief transform passphrase into another language/mnemonic source
Poco::SharedPtr<Passphrase> transform(const Mnemonic* targetWordSource); Poco::AutoPtr<Passphrase> transform(const Mnemonic* targetWordSource);
//! \brief replace utf8 characters with html special character encoding //! \brief replace utf8 characters with html special character encoding
//! //!
@ -26,6 +31,7 @@ public:
const Poco::UInt16* getWordIndices(); const Poco::UInt16* getWordIndices();
protected: protected:
//! \return true if ok
bool createWordIndices(); bool createWordIndices();
std::string mPassphraseString; std::string mPassphraseString;

View File

@ -1,5 +1,6 @@
#include "MemoryManager.h" #include "MemoryManager.h"
#include "ErrorManager.h" #include "ErrorManager.h"
#include "sodium.h"
#define _DEFAULT_PAGE_SIZE 10 #define _DEFAULT_PAGE_SIZE 10
@ -17,6 +18,40 @@ MemoryBin::~MemoryBin()
} }
} }
std::string MemoryBin::convertToHex()
{
auto mm = MemoryManager::getInstance();
Poco::UInt32 hexSize = mSize * 2 + 1;
auto hexMem = mm->getFreeMemory(hexSize);
//char* hexString = (char*)malloc(hexSize);
memset(*hexMem, 0, hexSize);
sodium_bin2hex(*hexMem, hexSize, mData, mSize);
std::string hex = (char*)*hexMem;
// free(hexString);
mm->releaseMemory(hexMem);
return hex;
}
int MemoryBin::convertFromHex(const std::string& hex)
{
auto mm = MemoryManager::getInstance();
size_t hexSize = hex.size();
size_t binSize = (hexSize) / 2;
if (binSize > mSize) {
return -1;
}
memset(mData, 0, mSize);
size_t resultBinSize = 0;
if (0 != sodium_hex2bin(mData, binSize, hex.data(), hexSize, nullptr, &resultBinSize, nullptr)) {
return -2;
}
return 0;
}
// ************************************************************* // *************************************************************

View File

@ -41,6 +41,12 @@ public:
inline unsigned char* data() { return mData; } inline unsigned char* data() { return mData; }
inline const unsigned char* data() const { return mData; } inline const unsigned char* data() const { return mData; }
std::string convertToHex();
//! \return 0 if ok
//! -1 if bin is to small
//! -2 if hex is invalid
int convertFromHex(const std::string& hex);
protected: protected:
MemoryBin(Poco::UInt32 size); MemoryBin(Poco::UInt32 size);
~MemoryBin(); ~MemoryBin();

View File

@ -79,9 +79,9 @@ namespace controller {
} }
} }
} }
else {
return "<invalid passphrase>"; return "<invalid passphrase>";
}
} }
std::string UserBackups::formatPassphrase(std::string passphrase, int targetLinesCount/* = 5*/) std::string UserBackups::formatPassphrase(std::string passphrase, int targetLinesCount/* = 5*/)

View File

@ -0,0 +1,35 @@
#include "AutoPtrContainer.h"
#include <assert.h>
AutoPtrContainer::AutoPtrContainer() : mReferenceCount(1)
{
}
AutoPtrContainer::AutoPtrContainer(int referenceCount)
: mReferenceCount(referenceCount)
{
}
AutoPtrContainer::~AutoPtrContainer()
{
mReferenceCount = 0;
}
void AutoPtrContainer::duplicate()
{
Poco::ScopedLock<Poco::FastMutex> lock(mReferenceCountMutex);
mReferenceCount++;
}
void AutoPtrContainer::release()
{
Poco::ScopedLock<Poco::FastMutex> lock(mReferenceCountMutex);
mReferenceCount--;
assert(mReferenceCount >= 0);
if (0 == mReferenceCount) {
delete this;
}
}

View File

@ -0,0 +1,35 @@
#ifndef __GRADIDO_LOGIN_SERVER_LIB_AUTO_PTR_CONTAINER
#define __GRADIDO_LOGIN_SERVER_LIB_AUTO_PTR_CONTAINER
/*!
* \author: Dario Rekowski
*
* \date: 02.06.2020
*
* \brief: keep track over reserved instances, for using with Poco::AutoPtr
*/
#include "Poco/Mutex.h"
class AutoPtrContainer
{
public:
AutoPtrContainer();
AutoPtrContainer(int referenceCount);
void duplicate();
void release();
protected:
// called only from release
virtual ~AutoPtrContainer();
private:
int mReferenceCount;
Poco::FastMutex mReferenceCountMutex;
};
#endif //__GRADIDO_LOGIN_SERVER_LIB_AUTO_PTR_CONTAINER

View File

@ -0,0 +1,71 @@
#include "TestPassphrase.h"
#include "../../Crypto/Passphrase.h"
#include "../../SingletonManager/MemoryManager.h"
#include "sodium.h"
#include "gtest/gtest.h"
TestPassphrase::TestPassphrase()
{
}
TestPassphrase::~TestPassphrase()
{
}
int TestPassphrase::init()
{
return 0;
}
//! \return 0 if okay, else return != 0
int TestPassphrase::test()
{
return 0;
}
void PassphraseTest::SetUp()
{
mPassphrasesForTesting.push_back(PassphraseDataSet(
"beauty slight skill maze wrap neither table term pizza journey unusual fence mind buzz scrap height critic service table knock fury shrimp curious fog",
ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER,
"6fa7180b132e1248c649fc7b2e422ad57663299f85bd88b8b8031dce28b501a8"
));
mPassphrasesForTesting.push_back(PassphraseDataSet(
"oftmals bist bietet spalten Datenbank Masse str&auml;flich hervor Derartig Hallo christlich Brief iPhone einpendeln telefonieren musizieren gigantisch Orchester zirkulieren essen gilt Erich Dollar money",
ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER,
"8943813a623863dd7c5e5b248e408ac8a8851ef758275b6043a06e9b5832c36c"
));
mPassphrasesForTesting.push_back(PassphraseDataSet(
"tief Acker Abgaben jenseits Revolution verdeckt Entdeckung Sanktion sammeln Umdrehung regulieren murmeln Erkenntnis hart zwar zuspitzen indem fegen bomber zw&ouml;lf Mobbing divers Inspiration Krieg",
ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER,
"d62f14173ae5d66b06753cc9d69d5471913ffc6053feedac2acf901eef3582a9"
));
}
TEST_F(PassphraseTest, detectMnemonic) {
for (auto it = mPassphrasesForTesting.begin(); it != mPassphrasesForTesting.end(); it++) {
auto testDataSet = *it;
EXPECT_EQ(Passphrase::detectMnemonic(testDataSet.passphrase), &ServerConfig::g_Mnemonic_WordLists[testDataSet.mnemonicType]);
}
EXPECT_FALSE(Passphrase::detectMnemonic("Dies ist eine ungültige Passphrase"));
}
TEST_F(PassphraseTest, detectMnemonicWithPubkey) {
auto mm = MemoryManager::getInstance();
auto pubkeyBin = mm->getFreeMemory(crypto_sign_PUBLICKEYBYTES);
for (auto it = mPassphrasesForTesting.begin(); it != mPassphrasesForTesting.end(); it++) {
auto testDataSet = *it;
//testDataSet.pubkeyHex
ASSERT_FALSE(pubkeyBin->convertFromHex(testDataSet.pubkeyHex));
EXPECT_EQ(Passphrase::detectMnemonic(testDataSet.passphrase, pubkeyBin), &ServerConfig::g_Mnemonic_WordLists[testDataSet.mnemonicType]);
}
mm->releaseMemory(pubkeyBin);
}

View File

@ -0,0 +1,43 @@
#ifndef __GRADIDO_LOGIN_SERVER_TEST_CRYPTO_TEST_PASSPHRASE_H
#define __GRADIDO_LOGIN_SERVER_TEST_CRYPTO_TEST_PASSPHRASE_H
#include "../Test.h"
#include "../../ServerConfig.h"
#include "gtest/gtest.h"
class TestPassphrase : public Test
{
public:
TestPassphrase();
~TestPassphrase();
//! \return 0 if init okay, else return != 0
int init();
//! \return 0 if okay, else return != 0
int test();
const char* getName() { return "TestPassphrase"; }
protected:
};
class PassphraseTest : public ::testing::Test {
protected:
void SetUp() override;
struct PassphraseDataSet
{
PassphraseDataSet(std::string _passphrase, ServerConfig::Mnemonic_Types _type, std::string _pubkeyHex)
: passphrase(_passphrase), mnemonicType(_type), pubkeyHex(_pubkeyHex) {}
std::string passphrase;
ServerConfig::Mnemonic_Types mnemonicType;
std::string pubkeyHex;
};
std::vector<PassphraseDataSet> mPassphrasesForTesting;
// void TearDown() override {}
};
#endif //__GRADIDO_LOGIN_SERVER_TEST_CRYPTO_TEST_PASSPHRASE_H

View File

@ -1,6 +1,7 @@
#include "main.h" #include "main.h"
#include <list> #include <list>
#include "gtest/gtest.h"
std::list<Test*> gTests; std::list<Test*> gTests;
@ -9,6 +10,7 @@ void fillTests()
gTests.push_back(new TestTasks()); gTests.push_back(new TestTasks());
gTests.push_back(new TestHash()); gTests.push_back(new TestHash());
gTests.push_back(new TestRegExp()); gTests.push_back(new TestRegExp());
gTests.push_back(new TestPassphrase());
// gTests.push_back(new LoginTest()); // gTests.push_back(new LoginTest());
} }
@ -53,5 +55,7 @@ int main(int argc, char** argv)
load(); load();
run(); run();
ende(); ende();
return 42; ::testing::InitGoogleTest(&argc, argv);
} return RUN_ALL_TESTS();
//return 42;
}

View File

@ -2,3 +2,4 @@
#include "TestTasks.h" #include "TestTasks.h"
#include "TestHash.h" #include "TestHash.h"
#include "TestRegExp.h" #include "TestRegExp.h"
#include "crypto/TestPassphrase.h"