From 1206b6105db626d91b45d4d4b3d85eaf9e0eb249 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Mon, 24 Aug 2020 18:24:48 +0200 Subject: [PATCH 001/195] include grpc manuell in cmake project, debug windows, other configurations are to come --- .gitmodules | 3 +++ CMakeLists.txt | 6 ++++++ README | 7 +++++++ compile_proto.sh | 5 +++-- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2f85c0ab3..94115f227 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "dependencies/spirit-po"] path = dependencies/spirit-po url = https://github.com/cbeck88/spirit-po.git +[submodule "dependencies/grpc"] + path = dependencies/grpc + url = https://github.com/grpc/grpc.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f4e05b75..e544d1bac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ include_directories( "dependencies/mariadb-connector-c/include" "dependencies/mariadb-connector-c/build/include" "dependencies/spirit-po/include" + "dependencies/grpc/include" "src/cpp/proto" #"dependencies/mariadb-connector-c/build/include" #"dependencies/mariadb-connector-c/include" @@ -91,6 +92,10 @@ find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-conne #find_library(MYSQL_LIBRARIES_DEBUG mariadbclient.lib PATHS "import/mariadb/lib/debug") find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build/Debug" REQUIRED) +set(GRPC_PATH "dependencies/grpc/_build/Debug") +find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) +set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION}) set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") #set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") @@ -139,6 +144,7 @@ target_link_libraries(Gradido_LoginServer ${CONAN_LIBS} ${IROHA_ED25519}) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) +TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS}) else(WIN32) target_link_libraries(Gradido_LoginServer libmariadb protoc protobuf -pthread) endif(WIN32) diff --git a/README b/README index f6ca48a88..89783a878 100644 --- a/README +++ b/README @@ -20,6 +20,13 @@ cmake -DWITH_SSL=OFF .. cd ../../../ +cd dependencies/grpc +mkdir _build +cd _build +cmake .. +make +cd ../../../ + # get more dependencies with conan (need conan from https://conan.io/) mkdir build && cd build conan remote add inexor https://api.bintray.com/conan/inexorgame/inexor-conan diff --git a/compile_proto.sh b/compile_proto.sh index 16e3f975f..7e823733d 100755 --- a/compile_proto.sh +++ b/compile_proto.sh @@ -6,12 +6,13 @@ if [ ! -d "./src/cpp/proto/gradido" ] ; then mkdir ./src/cpp/proto/gradido fi -protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto +./protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto if [ ! -d "./src/cpp/proto/hedera" ] ; then mkdir ./src/cpp/proto/hedera fi -protoc --cpp_out=./src/cpp/proto/hedera --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto +./protoc --plugin=protoc-gen-grpc=./grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto + From d0b105b9e5cf8636c1cf62d0f66109eecdbd0007 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Tue, 25 Aug 2020 11:26:14 +0200 Subject: [PATCH 002/195] add empty files for hedera proto wrappers --- CMakeLists.txt | 4 +++- dependencies/grpc | 1 + src/cpp/model/hedera/ConsensusCreateTopic.cpp | 0 src/cpp/model/hedera/ConsensusCreateTopic.h | 0 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp | 0 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h | 0 src/cpp/model/hedera/ConsensusSubmitMessage.cpp | 0 src/cpp/model/hedera/ConsensusSubmitMessage.h | 0 src/cpp/model/hedera/Query.cpp | 0 src/cpp/model/hedera/Query.h | 0 src/cpp/model/hedera/QueryHeader.cpp | 0 src/cpp/model/hedera/QueryHeader.h | 0 src/cpp/model/hedera/Response.cpp | 0 src/cpp/model/hedera/Response.h | 0 src/cpp/model/hedera/ResponseHeader.cpp | 0 src/cpp/model/hedera/ResponseHeader.h | 0 src/cpp/model/hedera/Transaction.cpp | 0 src/cpp/model/hedera/Transaction.h | 0 src/cpp/model/hedera/TransactionBody.cpp | 0 src/cpp/model/hedera/TransactionBody.h | 0 20 files changed, 4 insertions(+), 1 deletion(-) create mode 160000 dependencies/grpc create mode 100644 src/cpp/model/hedera/ConsensusCreateTopic.cpp create mode 100644 src/cpp/model/hedera/ConsensusCreateTopic.h create mode 100644 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp create mode 100644 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h create mode 100644 src/cpp/model/hedera/ConsensusSubmitMessage.cpp create mode 100644 src/cpp/model/hedera/ConsensusSubmitMessage.h create mode 100644 src/cpp/model/hedera/Query.cpp create mode 100644 src/cpp/model/hedera/Query.h create mode 100644 src/cpp/model/hedera/QueryHeader.cpp create mode 100644 src/cpp/model/hedera/QueryHeader.h create mode 100644 src/cpp/model/hedera/Response.cpp create mode 100644 src/cpp/model/hedera/Response.h create mode 100644 src/cpp/model/hedera/ResponseHeader.cpp create mode 100644 src/cpp/model/hedera/ResponseHeader.h create mode 100644 src/cpp/model/hedera/Transaction.cpp create mode 100644 src/cpp/model/hedera/Transaction.h create mode 100644 src/cpp/model/hedera/TransactionBody.cpp create mode 100644 src/cpp/model/hedera/TransactionBody.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e544d1bac..b16d3bb4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ FILE(GLOB LIB_SRC "src/cpp/lib/*.h" "src/cpp/lib/*.cpp") FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp") FILE(GLOB MODEL_TABLE "src/cpp/model/table/*.h" "src/cpp/model/table/*.cpp") FILE(GLOB MODEL_EMAIL "src/cpp/model/email/*.h" "src/cpp/model/email/*.cpp") +FILE(GLOB MODEL_HEDERA "src/cpp/model/hedera/*.h" "src/cpp/model/hedera/*.cpp") FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp") FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h") FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h") @@ -44,7 +45,7 @@ FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controll SET(LOCAL_SRCS ${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} - ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} + ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_HEDERA} ${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS} ${PROTO_GRADIDO} ${PROTO_HEDERA} ) @@ -63,6 +64,7 @@ source_group("Crypto" FILES ${CRYPTO}) source_group("tasks" FILES ${TASKS}) source_group("model\\table" FILES ${MODEL_TABLE}) source_group("model\\email" FILES ${MODEL_EMAIL}) +source_group("model\\hedera" FILES ${MODEL_HEDERA}) source_group("model" FILES ${MODEL}) source_group("mysql" FILES ${MYSQL}) source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) diff --git a/dependencies/grpc b/dependencies/grpc new file mode 160000 index 000000000..f57a0619b --- /dev/null +++ b/dependencies/grpc @@ -0,0 +1 @@ +Subproject commit f57a0619bc5697ea98c2d5b2c983c7024f43a5db diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.h b/src/cpp/model/hedera/ConsensusCreateTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.cpp b/src/cpp/model/hedera/ConsensusSubmitMessage.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.h b/src/cpp/model/hedera/ConsensusSubmitMessage.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/QueryHeader.cpp b/src/cpp/model/hedera/QueryHeader.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/QueryHeader.h b/src/cpp/model/hedera/QueryHeader.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ResponseHeader.cpp b/src/cpp/model/hedera/ResponseHeader.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ResponseHeader.h b/src/cpp/model/hedera/ResponseHeader.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h new file mode 100644 index 000000000..e69de29bb From 8549c8821c201fcce2d0597b00a7cd527d226763 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Tue, 25 Aug 2020 12:10:02 +0200 Subject: [PATCH 003/195] add nearly empty hedera topic management page, and additional wrapper for hedera proto --- src/cpp/model/hedera/ConsensusDeleteTopic.cpp | 0 src/cpp/model/hedera/ConsensusDeleteTopic.h | 0 src/cpp/model/hedera/ConsensusUpdateTopic.cpp | 0 src/cpp/model/hedera/ConsensusUpdateTopic.h | 0 src/cpsp/adminHederaTopic.cpsp | 21 +++++++++++++++++++ 5 files changed, 21 insertions(+) create mode 100644 src/cpp/model/hedera/ConsensusDeleteTopic.cpp create mode 100644 src/cpp/model/hedera/ConsensusDeleteTopic.h create mode 100644 src/cpp/model/hedera/ConsensusUpdateTopic.cpp create mode 100644 src/cpp/model/hedera/ConsensusUpdateTopic.h create mode 100644 src/cpsp/adminHederaTopic.cpsp diff --git a/src/cpp/model/hedera/ConsensusDeleteTopic.cpp b/src/cpp/model/hedera/ConsensusDeleteTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusDeleteTopic.h b/src/cpp/model/hedera/ConsensusDeleteTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusUpdateTopic.cpp b/src/cpp/model/hedera/ConsensusUpdateTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusUpdateTopic.h b/src/cpp/model/hedera/ConsensusUpdateTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpsp/adminHederaTopic.cpsp b/src/cpsp/adminHederaTopic.cpsp new file mode 100644 index 000000000..bc1fcf36e --- /dev/null +++ b/src/cpsp/adminHederaTopic.cpsp @@ -0,0 +1,21 @@ +<%@ page class="AdminHederaTopic" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + + +%> +<%% + const char* pageName = "Admin Hedera Topic"; + + +%><%@ include file="header_old.cpsp" %> +
+

Admin Hedera Topic

+ <%= getErrorsHtml() %> + +
+<%@ include file="footer.cpsp" %> From 0c3e69b045d97ba56134a756969083ccf0ec3662 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Tue, 25 Aug 2020 12:59:34 +0200 Subject: [PATCH 004/195] add new tables and model/table empty files for them --- skeema/gradido_login/crypto_keys.sql | 7 +++++++ skeema/gradido_login/groups.sql | 7 +++++++ skeema/gradido_login/hedera_accounts.sql | 9 +++++++++ skeema/gradido_login/hedera_ids.sql | 7 +++++++ skeema/gradido_login/hedera_topics.sql | 13 +++++++++++++ src/cpp/model/table/CryptoKeys.cpp | 0 src/cpp/model/table/CryptoKeys.h | 0 src/cpp/model/table/Groups.cpp | 0 src/cpp/model/table/Groups.h | 0 src/cpp/model/table/HederaAccounts.cpp | 0 src/cpp/model/table/HederaAccounts.h | 0 src/cpp/model/table/HederaIds.cpp | 0 src/cpp/model/table/HederaIds.h | 0 src/cpp/model/table/HederaTopics.cpp | 0 src/cpp/model/table/HederaTopics.h | 0 15 files changed, 43 insertions(+) create mode 100644 skeema/gradido_login/crypto_keys.sql create mode 100644 skeema/gradido_login/groups.sql create mode 100644 skeema/gradido_login/hedera_accounts.sql create mode 100644 skeema/gradido_login/hedera_ids.sql create mode 100644 skeema/gradido_login/hedera_topics.sql create mode 100644 src/cpp/model/table/CryptoKeys.cpp create mode 100644 src/cpp/model/table/CryptoKeys.h create mode 100644 src/cpp/model/table/Groups.cpp create mode 100644 src/cpp/model/table/Groups.h create mode 100644 src/cpp/model/table/HederaAccounts.cpp create mode 100644 src/cpp/model/table/HederaAccounts.h create mode 100644 src/cpp/model/table/HederaIds.cpp create mode 100644 src/cpp/model/table/HederaIds.h create mode 100644 src/cpp/model/table/HederaTopics.cpp create mode 100644 src/cpp/model/table/HederaTopics.h diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql new file mode 100644 index 000000000..971c56a7b --- /dev/null +++ b/skeema/gradido_login/crypto_keys.sql @@ -0,0 +1,7 @@ +CREATE TABLE `crypto_keys` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `private_key` VARBINARY(64) NOT NULL, + `public_key` BINARY(32) NOT NULL, + `crypto_key_type_id` INT NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/groups.sql b/skeema/gradido_login/groups.sql new file mode 100644 index 000000000..c3d0bc787 --- /dev/null +++ b/skeema/gradido_login/groups.sql @@ -0,0 +1,7 @@ +CREATE TABLE `groups` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `alias` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `description` TEXT NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql new file mode 100644 index 000000000..fc2ad9735 --- /dev/null +++ b/skeema/gradido_login/hedera_accounts.sql @@ -0,0 +1,9 @@ +CREATE TABLE `hedera_accounts` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `user_id` INT UNSIGNED NOT NULL, + `account_hedera_id` INT UNSIGNED NOT NULL, + `account_key_id` INT UNSIGNED NOT NULL, + `balance` BIGINT UNSIGNED NOT NULL DEFAULT '0', + `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/hedera_ids.sql b/skeema/gradido_login/hedera_ids.sql new file mode 100644 index 000000000..624a02207 --- /dev/null +++ b/skeema/gradido_login/hedera_ids.sql @@ -0,0 +1,7 @@ +CREATE TABLE `hedera_ids` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `shardNum` BIGINT NOT NULL DEFAULT '0', + `realmNum` BIGINT NOT NULL DEFAULT '0', + `num` BIGINT NOT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql new file mode 100644 index 000000000..c1fa90f2b --- /dev/null +++ b/skeema/gradido_login/hedera_topics.sql @@ -0,0 +1,13 @@ +CREATE TABLE `hedera_topics` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `topic_hedera_id` INT UNSIGNED NOT NULL, + `auto_renew_account_hedera_id` INT UNSIGNED NULL, + `auto_renew_period` INT UNSIGNED NOT NULL DEFAULT '0', + `group_id` INT UNSIGNED NOT NULL, + `admin_key_id` INT UNSIGNED NULL, + `submit_key_id` INT UNSIGNED NULL, + `current_timeout` BIGINT UNSIGNED NOT NULL DEFAULT '0', + `sequence_number` BIGINT UNSIGNED NULL DEFAULT '0', + `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/model/table/CryptoKeys.cpp b/src/cpp/model/table/CryptoKeys.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/CryptoKeys.h b/src/cpp/model/table/CryptoKeys.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/Groups.cpp b/src/cpp/model/table/Groups.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/Groups.h b/src/cpp/model/table/Groups.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaAccounts.cpp b/src/cpp/model/table/HederaAccounts.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaAccounts.h b/src/cpp/model/table/HederaAccounts.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaIds.cpp b/src/cpp/model/table/HederaIds.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaIds.h b/src/cpp/model/table/HederaIds.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaTopics.cpp b/src/cpp/model/table/HederaTopics.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaTopics.h b/src/cpp/model/table/HederaTopics.h new file mode 100644 index 000000000..e69de29bb From 5d3fbcfdfa9a1ab1e819d5234272021402e153e0 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 16:17:28 +0200 Subject: [PATCH 005/195] rename AuthenticatedEncryption to SecretKeyCryptography --- src/cpp/Crypto/KeyPairEd25519.cpp | 4 ++-- src/cpp/Crypto/KeyPairEd25519.h | 4 ++-- ...dEncryption.cpp => SecretKeyCryptography.cpp} | 16 ++++++++-------- ...catedEncryption.h => SecretKeyCryptography.h} | 14 +++++++------- src/cpp/controller/User.cpp | 10 +++++----- src/cpp/controller/User.h | 6 +++--- .../AuthenticatedEncryptionCreateKeyTask.cpp | 4 ++-- .../test/crypto/TestAuthenticatedEncryption.cpp | 10 +++++----- 8 files changed, 34 insertions(+), 34 deletions(-) rename src/cpp/Crypto/{AuthenticatedEncryption.cpp => SecretKeyCryptography.cpp} (86%) rename src/cpp/Crypto/{AuthenticatedEncryption.h => SecretKeyCryptography.h} (85%) diff --git a/src/cpp/Crypto/KeyPairEd25519.cpp b/src/cpp/Crypto/KeyPairEd25519.cpp index ee8cabfa0..392bf5e8e 100644 --- a/src/cpp/Crypto/KeyPairEd25519.cpp +++ b/src/cpp/Crypto/KeyPairEd25519.cpp @@ -151,13 +151,13 @@ MemoryBin* KeyPairEd25519::sign(const unsigned char* message, size_t messageSize } -MemoryBin* KeyPairEd25519::getCryptedPrivKey(const Poco::AutoPtr password) const +MemoryBin* KeyPairEd25519::getCryptedPrivKey(const Poco::AutoPtr password) const { if (password.isNull()) return nullptr; if (!mSodiumSecret) return nullptr; MemoryBin* encryptedKey = nullptr; - if (AuthenticatedEncryption::AUTH_ENCRYPT_OK == password->encrypt(mSodiumSecret, &encryptedKey)) { + if (SecretKeyCryptography::AUTH_ENCRYPT_OK == password->encrypt(mSodiumSecret, &encryptedKey)) { return encryptedKey; } else { diff --git a/src/cpp/Crypto/KeyPairEd25519.h b/src/cpp/Crypto/KeyPairEd25519.h index 7b3f11d4b..75a1ce9f1 100644 --- a/src/cpp/Crypto/KeyPairEd25519.h +++ b/src/cpp/Crypto/KeyPairEd25519.h @@ -13,7 +13,7 @@ #include "sodium.h" -#include "AuthenticatedEncryption.h" +#include "SecretKeyCryptography.h" #include "Passphrase.h" class KeyPairEd25519 : public IKeyPair @@ -63,7 +63,7 @@ public: inline bool hasPrivateKey() const { return mSodiumSecret != nullptr; } //! \brief only way to get a private key.. encrypted - MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; + MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; protected: diff --git a/src/cpp/Crypto/AuthenticatedEncryption.cpp b/src/cpp/Crypto/SecretKeyCryptography.cpp similarity index 86% rename from src/cpp/Crypto/AuthenticatedEncryption.cpp rename to src/cpp/Crypto/SecretKeyCryptography.cpp index 421537a66..0685ecaff 100644 --- a/src/cpp/Crypto/AuthenticatedEncryption.cpp +++ b/src/cpp/Crypto/SecretKeyCryptography.cpp @@ -1,22 +1,22 @@ -#include "AuthenticatedEncryption.h" +#include "SecretKeyCryptography.h" #include "sodium.h" #include "../ServerConfig.h" #include #include "../lib/Profiler.h" -AuthenticatedEncryption::AuthenticatedEncryption() +SecretKeyCryptography::SecretKeyCryptography() : mOpsLimit(10), mMemLimit(33554432), mAlgo(2), mEncryptionKey(nullptr), mEncryptionKeyHash(0) { } -AuthenticatedEncryption::AuthenticatedEncryption(unsigned long long opslimit, size_t memlimit, int algo) +SecretKeyCryptography::SecretKeyCryptography(unsigned long long opslimit, size_t memlimit, int algo) : mOpsLimit(opslimit), mMemLimit(memlimit), mAlgo(algo), mEncryptionKey(nullptr), mEncryptionKeyHash(0) { } -AuthenticatedEncryption::~AuthenticatedEncryption() +SecretKeyCryptography::~SecretKeyCryptography() { if (mEncryptionKey) { MemoryManager::getInstance()->releaseMemory(mEncryptionKey); @@ -24,7 +24,7 @@ AuthenticatedEncryption::~AuthenticatedEncryption() } } -AuthenticatedEncryption::ResultType AuthenticatedEncryption::createKey(const std::string& salt_parameter, const std::string& passwd) +SecretKeyCryptography::ResultType SecretKeyCryptography::createKey(const std::string& salt_parameter, const std::string& passwd) { assert(crypto_hash_sha512_BYTES >= crypto_pwhash_SALTBYTES); @@ -79,7 +79,7 @@ AuthenticatedEncryption::ResultType AuthenticatedEncryption::createKey(const std return AUTH_ENCRYPT_OK; } -AuthenticatedEncryption::ResultType AuthenticatedEncryption::encrypt(const MemoryBin* message, MemoryBin** encryptedMessage) const +SecretKeyCryptography::ResultType SecretKeyCryptography::encrypt(const MemoryBin* message, MemoryBin** encryptedMessage) const { assert(message && encryptedMessage); std::shared_lock _lock(mWorkingMutex); @@ -111,7 +111,7 @@ AuthenticatedEncryption::ResultType AuthenticatedEncryption::encrypt(const Memor return AUTH_ENCRYPT_OK; } -AuthenticatedEncryption::ResultType AuthenticatedEncryption::decrypt(const unsigned char* encryptedMessage, size_t encryptedMessageSize, MemoryBin** message) const +SecretKeyCryptography::ResultType SecretKeyCryptography::decrypt(const unsigned char* encryptedMessage, size_t encryptedMessageSize, MemoryBin** message) const { assert(message); std::shared_lock _lock(mWorkingMutex); @@ -139,7 +139,7 @@ AuthenticatedEncryption::ResultType AuthenticatedEncryption::decrypt(const unsig return AUTH_DECRYPT_OK; } -const char* AuthenticatedEncryption::getErrorMessage(ResultType type) +const char* SecretKeyCryptography::getErrorMessage(ResultType type) { switch (type) { case AUTH_ENCRYPT_OK: return "everything is ok"; diff --git a/src/cpp/Crypto/AuthenticatedEncryption.h b/src/cpp/Crypto/SecretKeyCryptography.h similarity index 85% rename from src/cpp/Crypto/AuthenticatedEncryption.h rename to src/cpp/Crypto/SecretKeyCryptography.h index a19e0f856..0a0a16072 100644 --- a/src/cpp/Crypto/AuthenticatedEncryption.h +++ b/src/cpp/Crypto/SecretKeyCryptography.h @@ -17,13 +17,13 @@ * * \date: 07-06-2020 * - * \brief: Wrapper Class for make using libsodium authenticated encryption easy, used for encrypt private keys for user + * \brief: Wrapper Class for make using libsodium secret key encryption easy, used for encrypt private keys for user with pwhash * */ typedef Poco::UInt64 KeyHashed; -class AuthenticatedEncryption : public AutoPtrContainer +class SecretKeyCryptography : public AutoPtrContainer { public: @@ -37,20 +37,20 @@ public: }; //! \brief init with default algorithms parameter - AuthenticatedEncryption(); + SecretKeyCryptography(); //! \brief init with custom algorithms parameter //! //! details see in libsodium crypto_pwhash - AuthenticatedEncryption(unsigned long long opslimit, size_t memlimit, int algo); + SecretKeyCryptography(unsigned long long opslimit, size_t memlimit, int algo); - ~AuthenticatedEncryption(); + ~SecretKeyCryptography(); inline KeyHashed getKeyHashed() const { std::shared_lock _lock(mWorkingMutex); return mEncryptionKeyHash; } - inline bool operator == (const Poco::AutoPtr& b) const { + inline bool operator == (const Poco::AutoPtr& b) const { return isTheSame(b); } - inline bool isTheSame(const Poco::AutoPtr& b) const { + inline bool isTheSame(const Poco::AutoPtr& b) const { std::shared_lock _lock(mWorkingMutex); if (b.isNull()) return false; return mEncryptionKeyHash == b->getKeyHashed(); diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 19c9df5a9..605f11087 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -144,7 +144,7 @@ namespace controller { return -3; } observer->addTask(email_hash, TASK_OBSERVER_PASSWORD_CREATION); - Poco::AutoPtr authenticated_encryption(new AuthenticatedEncryption); + Poco::AutoPtr authenticated_encryption(new SecretKeyCryptography); assert(!authenticated_encryption.isNull() && model); authenticated_encryption->createKey(model->getEmail(), password); @@ -163,7 +163,7 @@ namespace controller { } else { - if (AuthenticatedEncryption::AUTH_DECRYPT_OK == authenticated_encryption->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { + if (SecretKeyCryptography::AUTH_DECRYPT_OK == authenticated_encryption->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { if (mGradidoKeyPair) { if (mGradidoKeyPair->isTheSame(clear_private_key) == 0) { mCanDecryptPrivateKey = true; @@ -225,7 +225,7 @@ namespace controller { auto email_hash = observer->makeHash(model->getEmail()); observer->addTask(email_hash, TASK_OBSERVER_PASSWORD_CREATION); - Poco::AutoPtr authenticated_encryption(new AuthenticatedEncryption); + Poco::AutoPtr authenticated_encryption(new SecretKeyCryptography); assert(!authenticated_encryption.isNull() && model); authenticated_encryption->createKey(model->getEmail(), password); @@ -234,7 +234,7 @@ namespace controller { } - int User::setNewPassword(Poco::AutoPtr passwd) + int User::setNewPassword(Poco::AutoPtr passwd) { std::unique_lock _lock(mSharedMutex); auto model = getModel(); @@ -249,7 +249,7 @@ namespace controller { if ((!mGradidoKeyPair || !mGradidoKeyPair->hasPrivateKey()) && model->hasPrivateKeyEncrypted()) { //if (!mGradidoKeyPair) mGradidoKeyPair = new KeyPairEd25519; MemoryBin* clear_private_key = nullptr; - if (AuthenticatedEncryption::AUTH_DECRYPT_OK == mPassword->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { + if (SecretKeyCryptography::AUTH_DECRYPT_OK == mPassword->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { if (mGradidoKeyPair && mGradidoKeyPair->isTheSame(clear_private_key) != 0) { delete mGradidoKeyPair; diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index e251beb19..a42678739 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -81,7 +81,7 @@ namespace controller { //! \return 1 = password changed, private key re-encrypted and saved into db //! \return 2 = password changed, only hash stored in db, couldn't load private key for re-encryption //! \return -1 = stored pubkey and private key didn't match - int setNewPassword(Poco::AutoPtr passwd); + int setNewPassword(Poco::AutoPtr passwd); //! \brief set authenticated encryption and save hash in db, also re encrypt private key if exist @@ -93,7 +93,7 @@ namespace controller { int setNewPassword(const std::string& password); //! \brief return AuthenticatedEncryption Auto Pointer - inline const Poco::AutoPtr getPassword() { + inline const Poco::AutoPtr getPassword() { std::shared_lock _lock(mSharedMutex); return mPassword; } @@ -129,7 +129,7 @@ namespace controller { std::string mPublicHex; - Poco::AutoPtr mPassword; + Poco::AutoPtr mPassword; KeyPairEd25519* mGradidoKeyPair; bool mCanDecryptPrivateKey; diff --git a/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp b/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp index a43b6223e..9cc2338a1 100644 --- a/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp +++ b/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp @@ -22,9 +22,9 @@ int AuthenticatedEncryptionCreateKeyTask::run() { auto em = ErrorManager::getInstance(); const static char* function_name = "AuthenticatedEncryptionCreateKeyTask::run"; - auto authenticated_encryption = new AuthenticatedEncryption; + auto authenticated_encryption = new SecretKeyCryptography; Profiler timeUsed; - if (AuthenticatedEncryption::AUTH_ENCRYPT_OK != authenticated_encryption->createKey(mUser->getModel()->getEmail(), mPassword)) { + if (SecretKeyCryptography::AUTH_ENCRYPT_OK != authenticated_encryption->createKey(mUser->getModel()->getEmail(), mPassword)) { em->addError(new Error(function_name, "error creating key")); em->addError(new ParamError(function_name, "for email", mUser->getModel()->getEmail())); em->addError(new ParamError(function_name, "strerror: ", strerror(errno))); diff --git a/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp b/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp index 93c19bc9b..e863e773d 100644 --- a/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp +++ b/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp @@ -1,6 +1,6 @@ #include "TestAuthenticatedEncryption.h" -#include "../../Crypto/AuthenticatedEncryption.h" +#include "../../Crypto/SecretKeyCryptography.h" #include "../../lib/Profiler.h" #include "../../lib/DataTypeConverter.h" @@ -12,12 +12,12 @@ void TestAuthenticatedEncryption::SetUp() } TEST_F(TestAuthenticatedEncryption, encryptDecryptTest) { - AuthenticatedEncryption authenticated_encryption; + SecretKeyCryptography authenticated_encryption; EXPECT_FALSE(authenticated_encryption.hasKey()); EXPECT_EQ(authenticated_encryption.getKeyHashed(), 0); Profiler time_used; - EXPECT_EQ(authenticated_encryption.createKey("dariofrodo@gmx.de", "r3an7d_spassw"), AuthenticatedEncryption::AUTH_ENCRYPT_OK); + EXPECT_EQ(authenticated_encryption.createKey("dariofrodo@gmx.de", "r3an7d_spassw"), SecretKeyCryptography::AUTH_ENCRYPT_OK); printf("create key duration: %s\n", time_used.string().data()); EXPECT_TRUE(authenticated_encryption.hasKey()); @@ -29,12 +29,12 @@ TEST_F(TestAuthenticatedEncryption, encryptDecryptTest) { memcpy(*test_message_bin, test_message.data(), test_message.size()); time_used.reset(); - EXPECT_EQ(authenticated_encryption.encrypt(test_message_bin, &encrypted_message), AuthenticatedEncryption::AUTH_ENCRYPT_OK); + EXPECT_EQ(authenticated_encryption.encrypt(test_message_bin, &encrypted_message), SecretKeyCryptography::AUTH_ENCRYPT_OK); printf("encrypt message duration: %s\n", time_used.string().data()); MemoryBin* decrypted_message = nullptr; time_used.reset(); - EXPECT_EQ(authenticated_encryption.decrypt(encrypted_message, &decrypted_message), AuthenticatedEncryption::AUTH_DECRYPT_OK); + EXPECT_EQ(authenticated_encryption.decrypt(encrypted_message, &decrypted_message), SecretKeyCryptography::AUTH_DECRYPT_OK); printf("decrypt message duration: %s\n", time_used.string().data()); EXPECT_EQ(std::string((const char*)*decrypted_message, decrypted_message->size()), test_message); From 67c8069eb6b009994eb351d3f25f2776b994c015 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 16:18:38 +0200 Subject: [PATCH 006/195] add binToHex with Poco::Nullable for easy use with public keys --- src/cpp/lib/DataTypeConverter.cpp | 10 ++++++++++ src/cpp/lib/DataTypeConverter.h | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index c3275ba49..a97cb8d0e 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -176,6 +176,16 @@ namespace DataTypeConverter return hexString; } + std::string binToHex(const Poco::Nullable& nullableBin) + { + if (nullableBin.isNull()) { + return "0x0"; + } + else { + return binToHex(nullableBin.value().content().data(), nullableBin.value().content().size()); + } + } + std::string pubkeyToHex(const unsigned char* pubkey) { auto mm = MemoryManager::getInstance(); diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index e1a419a93..46a767d97 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -5,9 +5,10 @@ #include "../SingletonManager/MemoryManager.h" #include "Poco/Timespan.h" +#include "Poco/Nullable.h" +#include "Poco/Data/LOB.h" #include "../SingletonManager/LanguageManager.h" - namespace DataTypeConverter { enum NumberParseState @@ -26,7 +27,9 @@ namespace DataTypeConverter { std::string binToBase64(const MemoryBin* data); + std::string binToHex(const unsigned char* data, size_t size); + std::string binToHex(const Poco::Nullable& nullableBin); inline std::string binToHex(const MemoryBin* data) { return binToHex(data->data(), data->size());} //! \param pubkey pointer to array with crypto_sign_PUBLICKEYBYTES size From 5fd66d48e7c0db0d63aa8a9bf9472bf0699a45e4 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 17:13:49 +0200 Subject: [PATCH 007/195] update skeema files, fill in empty model table classes for new mysql tables --- skeema/gradido_login/crypto_keys.sql | 12 ++-- skeema/gradido_login/elopage_buys.sql | 8 +-- skeema/gradido_login/email_opt_in.sql | 8 +-- skeema/gradido_login/email_opt_in_types.sql | 2 +- skeema/gradido_login/groups.sql | 15 ++--- skeema/gradido_login/hedera_accounts.sql | 18 +++--- skeema/gradido_login/hedera_ids.sql | 14 ++--- skeema/gradido_login/hedera_topics.sql | 25 ++++---- skeema/gradido_login/roles.sql | 4 +- skeema/gradido_login/user_backups.sql | 2 +- skeema/gradido_login/user_roles.sql | 2 +- skeema/gradido_login/users.sql | 10 +-- src/cpp/model/table/CryptoKeys.cpp | 70 +++++++++++++++++++++ src/cpp/model/table/CryptoKeys.h | 43 +++++++++++++ src/cpp/model/table/Groups.cpp | 57 +++++++++++++++++ src/cpp/model/table/Groups.h | 35 +++++++++++ src/cpp/model/table/HederaAccounts.cpp | 63 +++++++++++++++++++ src/cpp/model/table/HederaAccounts.h | 36 +++++++++++ src/cpp/model/table/HederaIds.cpp | 58 +++++++++++++++++ src/cpp/model/table/HederaIds.h | 36 +++++++++++ src/cpp/model/table/HederaTopics.cpp | 69 ++++++++++++++++++++ src/cpp/model/table/HederaTopics.h | 41 ++++++++++++ 22 files changed, 570 insertions(+), 58 deletions(-) diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index 971c56a7b..43b511db2 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,7 +1,7 @@ CREATE TABLE `crypto_keys` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `private_key` VARBINARY(64) NOT NULL, - `public_key` BINARY(32) NOT NULL, - `crypto_key_type_id` INT NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `id` int unsigned NOT NULL AUTO_INCREMENT, + `private_key` varbinary(64) NOT NULL, + `public_key` binary(32) NOT NULL, + `crypto_key_type_id` int NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/elopage_buys.sql b/skeema/gradido_login/elopage_buys.sql index be3464846..0be79a34b 100644 --- a/skeema/gradido_login/elopage_buys.sql +++ b/skeema/gradido_login/elopage_buys.sql @@ -1,15 +1,15 @@ CREATE TABLE `elopage_buys` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `elopage_user_id` int NOT NULL, `affiliate_program_id` int NOT NULL, `publisher_id` int NOT NULL, `order_id` int NOT NULL, `product_id` int NOT NULL, `product_price` int NOT NULL, - `payer_email` varchar(255) COLLATE utf8_bin NOT NULL, - `publisher_email` varchar(255) COLLATE utf8_bin NOT NULL, + `payer_email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `publisher_email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `payed` tinyint NOT NULL, `success_date` datetime NOT NULL, - `event` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `event` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/email_opt_in.sql b/skeema/gradido_login/email_opt_in.sql index 1589093e8..da4288475 100644 --- a/skeema/gradido_login/email_opt_in.sql +++ b/skeema/gradido_login/email_opt_in.sql @@ -1,11 +1,11 @@ CREATE TABLE `email_opt_in` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `verification_code` bigint unsigned NOT NULL, `email_opt_in_type_id` int NOT NULL, - `created` datetime NOT NULL DEFAULT current_timestamp(), - `resend_count` int DEFAULT 0, - `updated` DATETIME on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `resend_count` int DEFAULT '0', + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `verification_code` (`verification_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/email_opt_in_types.sql b/skeema/gradido_login/email_opt_in_types.sql index f46275727..dbcd2d272 100644 --- a/skeema/gradido_login/email_opt_in_types.sql +++ b/skeema/gradido_login/email_opt_in_types.sql @@ -1,5 +1,5 @@ CREATE TABLE `email_opt_in_types` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` varchar(255) NOT NULL, PRIMARY KEY (`id`) diff --git a/skeema/gradido_login/groups.sql b/skeema/gradido_login/groups.sql index c3d0bc787..8c5e143bb 100644 --- a/skeema/gradido_login/groups.sql +++ b/skeema/gradido_login/groups.sql @@ -1,7 +1,8 @@ -CREATE TABLE `groups` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `alias` VARCHAR(255) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `description` TEXT NULL DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file +CREATE TABLE `groups` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `alias` varchar(190) NOT NULL, + `name` varchar(255) NOT NULL, + `description` text, + PRIMARY KEY (`id`), + UNIQUE KEY `alias` (`alias`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql index fc2ad9735..23ffa33d1 100644 --- a/skeema/gradido_login/hedera_accounts.sql +++ b/skeema/gradido_login/hedera_accounts.sql @@ -1,9 +1,11 @@ CREATE TABLE `hedera_accounts` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `user_id` INT UNSIGNED NOT NULL, - `account_hedera_id` INT UNSIGNED NOT NULL, - `account_key_id` INT UNSIGNED NOT NULL, - `balance` BIGINT UNSIGNED NOT NULL DEFAULT '0', - `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL, + `account_hedera_id` int unsigned NOT NULL, + `account_key_id` int unsigned NOT NULL, + `balance` bigint unsigned NOT NULL DEFAULT '0', + `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `account_hedera_id` (`account_hedera_id`), + UNIQUE KEY `account_key_id` (`account_key_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/hedera_ids.sql b/skeema/gradido_login/hedera_ids.sql index 624a02207..b5fd26682 100644 --- a/skeema/gradido_login/hedera_ids.sql +++ b/skeema/gradido_login/hedera_ids.sql @@ -1,7 +1,7 @@ -CREATE TABLE `hedera_ids` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `shardNum` BIGINT NOT NULL DEFAULT '0', - `realmNum` BIGINT NOT NULL DEFAULT '0', - `num` BIGINT NOT NULL, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file +CREATE TABLE `hedera_ids` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `shardNum` bigint NOT NULL DEFAULT '0', + `realmNum` bigint NOT NULL DEFAULT '0', + `num` bigint NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index c1fa90f2b..6a58174c1 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -1,13 +1,14 @@ CREATE TABLE `hedera_topics` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `topic_hedera_id` INT UNSIGNED NOT NULL, - `auto_renew_account_hedera_id` INT UNSIGNED NULL, - `auto_renew_period` INT UNSIGNED NOT NULL DEFAULT '0', - `group_id` INT UNSIGNED NOT NULL, - `admin_key_id` INT UNSIGNED NULL, - `submit_key_id` INT UNSIGNED NULL, - `current_timeout` BIGINT UNSIGNED NOT NULL DEFAULT '0', - `sequence_number` BIGINT UNSIGNED NULL DEFAULT '0', - `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `id` int unsigned NOT NULL AUTO_INCREMENT, + `topic_hedera_id` int unsigned NOT NULL, + `auto_renew_account_hedera_id` int unsigned DEFAULT NULL, + `auto_renew_period` int unsigned NOT NULL DEFAULT '0', + `group_id` int unsigned NOT NULL, + `admin_key_id` int unsigned DEFAULT NULL, + `submit_key_id` int unsigned DEFAULT NULL, + `current_timeout` timestamp NOT NULL DEFAULT '0', + `sequence_number` bigint unsigned DEFAULT '0', + `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `topic_hedera_id` (`topic_hedera_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/roles.sql b/skeema/gradido_login/roles.sql index b9d51dd11..c99223961 100644 --- a/skeema/gradido_login/roles.sql +++ b/skeema/gradido_login/roles.sql @@ -1,7 +1,7 @@ CREATE TABLE `roles` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` varchar(255) NOT NULL, - `flags` bigint NOT NULL DEFAULT 0, + `flags` bigint NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/user_backups.sql b/skeema/gradido_login/user_backups.sql index 699c9a2c6..7e3b7d85a 100644 --- a/skeema/gradido_login/user_backups.sql +++ b/skeema/gradido_login/user_backups.sql @@ -1,5 +1,5 @@ CREATE TABLE `user_backups` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `passphrase` text NOT NULL, `mnemonic_type` int DEFAULT '-1', diff --git a/skeema/gradido_login/user_roles.sql b/skeema/gradido_login/user_roles.sql index ac9f0834c..a92154ce8 100644 --- a/skeema/gradido_login/user_roles.sql +++ b/skeema/gradido_login/user_roles.sql @@ -1,5 +1,5 @@ CREATE TABLE `user_roles` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `role_id` int NOT NULL, PRIMARY KEY (`id`) diff --git a/skeema/gradido_login/users.sql b/skeema/gradido_login/users.sql index 172f34b56..e3c7deec5 100644 --- a/skeema/gradido_login/users.sql +++ b/skeema/gradido_login/users.sql @@ -1,16 +1,16 @@ CREATE TABLE `users` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `email` varchar(191) NOT NULL, `first_name` varchar(150) NOT NULL, `last_name` varchar(255) DEFAULT '', `password` bigint unsigned NOT NULL, `pubkey` binary(32) DEFAULT NULL, `privkey` binary(80) DEFAULT NULL, - `created` datetime NOT NULL DEFAULT current_timestamp(), - `email_checked` tinyint NOT NULL DEFAULT 0, - `passphrase_shown` tinyint NOT NULL DEFAULT 0, + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `email_checked` tinyint NOT NULL DEFAULT '0', + `passphrase_shown` tinyint NOT NULL DEFAULT '0', `language` varchar(4) NOT NULL DEFAULT 'de', - `disabled` BOOLEAN NULL DEFAULT FALSE, + `disabled` tinyint DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/model/table/CryptoKeys.cpp b/src/cpp/model/table/CryptoKeys.cpp index e69de29bb..e159f51cc 100644 --- a/src/cpp/model/table/CryptoKeys.cpp +++ b/src/cpp/model/table/CryptoKeys.cpp @@ -0,0 +1,70 @@ +#include "CryptoKeys.h" +#include "../../lib/DataTypeConverter.h" +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + CryptoKeys::CryptoKeys() + { + + } + + CryptoKeys::~CryptoKeys() + { + + } + + std::string CryptoKeys::toString() + { + assert(mKeyType < KEY_TYPE_COUNT && mKeyType >= 0); + std::stringstream ss; + ss << "Key Type: " << typeToString(static_cast(mKeyType)) << std::endl; + ss << "Public Key: " << DataTypeConverter::binToHex(mPublicKey); + return ss.str(); + } + + + const char* CryptoKeys::typeToString(KeyType type) + { + switch (type) { + case KEY_TYPE_ED25519_REF10: return "ed25519 ref10"; + case KEY_TYPE_SODIUM_ED25519: return "sodium ed22519"; + } + return ""; + } + + Poco::Data::Statement CryptoKeys::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, private_key, public_key, crypto_key_type_id FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mPrivateKey), into(mPublicKey), into(mKeyType); + + return select; + } + + Poco::Data::Statement CryptoKeys::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where public_key = ?" + , into(mID), use(mPublicKey); + unlock(); + return select; + } + + + Poco::Data::Statement CryptoKeys::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (private_key, public_key, crypto_key_type_id) VALUES(?,?,?)" + , use(mPrivateKey), use(mPublicKey), use(mKeyType); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKeys.h b/src/cpp/model/table/CryptoKeys.h index e69de29bb..15991c70b 100644 --- a/src/cpp/model/table/CryptoKeys.h +++ b/src/cpp/model/table/CryptoKeys.h @@ -0,0 +1,43 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE + +#include "ModelBase.h" +#include "Poco/Types.h" + +namespace model { + namespace table { + + enum KeyType { + KEY_TYPE_SODIUM_ED25519, + KEY_TYPE_ED25519_REF10, + KEY_TYPE_COUNT + }; + + class CryptoKeys : public ModelBase + { + public: + CryptoKeys(); + ~CryptoKeys(); + + // generic db operations + const char* getTableName() const { return "crypto_keys"; } + std::string toString(); + + + static const char* typeToString(KeyType type); + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + Poco::Nullable mPrivateKey; + Poco::Nullable mPublicKey; + int mKeyType; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/Groups.cpp b/src/cpp/model/table/Groups.cpp index e69de29bb..e99780783 100644 --- a/src/cpp/model/table/Groups.cpp +++ b/src/cpp/model/table/Groups.cpp @@ -0,0 +1,57 @@ +#include "Groups.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + Groups::Groups() + { + } + + Groups::~Groups() + { + + } + + std::string Groups::toString() + { + std::stringstream ss; + ss << "Alias: " << mAlias << std::endl; + ss << "Name: " << mName << std::endl; + ss << "Description:" << mDescription << std::endl; + return ss.str(); + } + + Poco::Data::Statement Groups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, alias, name, description FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mAlias), into(mName), into(mDescription); + + return select; + } + Poco::Data::Statement Groups::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where alias = ?" + , into(mID), use(mAlias); + unlock(); + return select; + + } + Poco::Data::Statement Groups::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (alias, name, description) VALUES(?,?,?)" + , use(mAlias), use(mName), use(mDescription); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/Groups.h b/src/cpp/model/table/Groups.h index e69de29bb..adc5789c0 100644 --- a/src/cpp/model/table/Groups.h +++ b/src/cpp/model/table/Groups.h @@ -0,0 +1,35 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE + +#include "ModelBase.h" + +namespace model { + namespace table { + + class Groups : public ModelBase + { + public: + Groups(); + ~Groups(); + + // generic db operations + const char* getTableName() const { return "groups"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + std::string mAlias; + std::string mName; + std::string mDescription; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccounts.cpp b/src/cpp/model/table/HederaAccounts.cpp index e69de29bb..3c019374d 100644 --- a/src/cpp/model/table/HederaAccounts.cpp +++ b/src/cpp/model/table/HederaAccounts.cpp @@ -0,0 +1,63 @@ +#include "HederaAccounts.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + + HederaAccounts::HederaAccounts() + { + + } + + HederaAccounts::~HederaAccounts() + { + + } + + std::string HederaAccounts::toString() + { + std::stringstream ss; + ss << "user id: " << std::to_string(mUserId) << std::endl; + ss << "account hedera id: " << std::to_string(mAccountHederaId) << std::endl; + ss << "account crypto key id: " << std::to_string(mAccountKeyId) << std::endl; + // balance in tinybars, 100,000,000 tinybar = 1 HashBar + ss << "account balance: " << std::to_string((double)(mBalance) * 100000000.0) << " HBAR" << std::endl; + ss << "last update: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl; + + return ss.str(); + } + + Poco::Data::Statement HederaAccounts::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mUpdated); + + return select; + + } + Poco::Data::Statement HederaAccounts::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where account_hedera_id = ?" + , into(mID), use(mAccountHederaId); + unlock(); + return select; + } + Poco::Data::Statement HederaAccounts::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (user_id, account_hedera_id, account_key_id, balance) VALUES(?,?,?,?)" + , use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccounts.h b/src/cpp/model/table/HederaAccounts.h index e69de29bb..74b2063d4 100644 --- a/src/cpp/model/table/HederaAccounts.h +++ b/src/cpp/model/table/HederaAccounts.h @@ -0,0 +1,36 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE + +#include "ModelBase.h" + +namespace model { + namespace table { + + class HederaAccounts : public ModelBase + { + public: + HederaAccounts(); + ~HederaAccounts(); + + // generic db operations + const char* getTableName() const { return "hedera_accounts"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + int mUserId; + int mAccountHederaId; + int mAccountKeyId; + Poco::UInt64 mBalance; + Poco::DateTime mUpdated; + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaIds.cpp b/src/cpp/model/table/HederaIds.cpp index e69de29bb..8eeed0e55 100644 --- a/src/cpp/model/table/HederaIds.cpp +++ b/src/cpp/model/table/HederaIds.cpp @@ -0,0 +1,58 @@ +#include "HederaIds.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + HederaIds::HederaIds() + { + + } + + HederaIds::~HederaIds() + { + + } + + std::string HederaIds::toString() + { + std::stringstream ss; + ss << "Shard Num: " << std::to_string(mShardNum) << std::endl; + ss << "Realm Num: " << std::to_string(mRealmNum) << std::endl; + ss << "Num: " << std::to_string(mNum) << std::endl; + return ss.str(); + } + + Poco::Data::Statement HederaIds::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + + Poco::Data::Statement select(session); + + select << "SELECT id, shardNum, realmNum, num FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mShardNum), into(mRealmNum), into(mNum); + + return select; + } + Poco::Data::Statement HederaIds::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where shardNum = ? AND realmNum = ? AND num = ?" + , into(mID), use(mShardNum), use(mRealmNum), use(mNum); + unlock(); + return select; + } + Poco::Data::Statement HederaIds::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (shardNum, realmNum, num) VALUES(?,?,?)" + , use(mShardNum), use(mRealmNum), use(mNum); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/HederaIds.h b/src/cpp/model/table/HederaIds.h index e69de29bb..eaa6612b8 100644 --- a/src/cpp/model/table/HederaIds.h +++ b/src/cpp/model/table/HederaIds.h @@ -0,0 +1,36 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE + +#include "ModelBase.h" +#include "Poco/Types.h" + +namespace model { + namespace table { + + class HederaIds : public ModelBase + { + public: + HederaIds(); + ~HederaIds(); + + // generic db operations + const char* getTableName() const { return "hedera_ids"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + Poco::UInt64 mShardNum; + Poco::UInt64 mRealmNum; + Poco::UInt64 mNum; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaTopics.cpp b/src/cpp/model/table/HederaTopics.cpp index e69de29bb..aeed1ea05 100644 --- a/src/cpp/model/table/HederaTopics.cpp +++ b/src/cpp/model/table/HederaTopics.cpp @@ -0,0 +1,69 @@ +#include "HederaTopics.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + HederaTopics::HederaTopics() + { + + } + + HederaTopics::~HederaTopics() + { + + } + + std::string HederaTopics::toString() + { + std::stringstream ss; + ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl; + ss << "Auto Renew Account Hedera id: " << std::to_string(mAutoRenewAccountHederaId) << std::endl; + ss << "Auto Renew Period: " << std::to_string(mAutoRenewPeriod) << " seconds" << std::endl; + ss << "Group id: " << std::to_string(mGroupId) << std::endl; + ss << "Admin Key id: " << std::to_string(mAdminKeyId) << std::endl; + ss << "Submit Key id: " << std::to_string(mSubmitKeyId) << std::endl; + ss << "Hedera Topic Tiemout: " << Poco::DateTimeFormatter::format(mCurrentTimeout, "%f.%m.%Y %H:%M:%S") << std::endl; + ss << "Hedera Topic Sequence Number: " << std::to_string(mSequenceNumber) << std::endl; + ss << "Updated: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl; + return ss.str(); + } + + Poco::Data::Statement HederaTopics::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period, " + << "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mTopicHederaId), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod) + , into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated); + + return select; + + } + Poco::Data::Statement HederaTopics::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where topic_hedera_id = ?" + , into(mID), use(mTopicHederaId); + unlock(); + return select; + } + Poco::Data::Statement HederaTopics::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period," + << " group_id, admin_key_id, submit_key_id, current_timeout, sequence_number) VALUES(?,?,?,?,?,?,?,?)" + , use(mTopicHederaId), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod) + , use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber), use(mUpdated); + unlock(); + return insert; + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/table/HederaTopics.h b/src/cpp/model/table/HederaTopics.h index e69de29bb..4584026ab 100644 --- a/src/cpp/model/table/HederaTopics.h +++ b/src/cpp/model/table/HederaTopics.h @@ -0,0 +1,41 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE + +#include "ModelBase.h" + +namespace model { + namespace table { + + class HederaTopics : public ModelBase + { + public: + HederaTopics(); + ~HederaTopics(); + + // generic db operations + const char* getTableName() const { return "hedera_topics"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + Poco::UInt32 mTopicHederaId; + Poco::UInt32 mAutoRenewAccountHederaId; + // in seconds + Poco::UInt32 mAutoRenewPeriod; + Poco::UInt32 mGroupId; + Poco::UInt32 mAdminKeyId; + Poco::UInt32 mSubmitKeyId; + Poco::DateTime mCurrentTimeout; + Poco::UInt64 mSequenceNumber; + Poco::DateTime mUpdated; + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE \ No newline at end of file From db87207bc0767050d2e2ebcdc67fae84e2d99113 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 18:02:08 +0200 Subject: [PATCH 008/195] Rename table models to singular --- doc/.gitignore | 1 + .../HTTPInterface/AdminCheckUserBackup.cpp | 6 ++-- .../HTTPInterface/AdminUserPasswordReset.cpp | 8 +++--- .../HTTPInterface/RepairDefectPassphrase.cpp | 4 +-- src/cpp/HTTPInterface/ResetPassword.cpp | 2 +- src/cpp/controller/User.cpp | 4 +-- .../{UserBackups.cpp => UserBackup.cpp} | 28 +++++++++---------- .../{UserBackups.h => UserBackup.h} | 14 +++++----- src/cpp/model/Session.cpp | 8 +++--- src/cpp/model/User.cpp | 4 +-- .../table/{CryptoKeys.cpp => CryptoKey.cpp} | 16 +++++------ .../model/table/{CryptoKeys.h => CryptoKey.h} | 6 ++-- src/cpp/model/table/{Groups.cpp => Group.cpp} | 14 +++++----- src/cpp/model/table/{Groups.h => Group.h} | 6 ++-- .../{HederaAccounts.cpp => HederaAccount.cpp} | 25 ++++++++++++----- .../{HederaAccounts.h => HederaAccount.h} | 10 +++++-- .../table/{HederaIds.cpp => HederaId.cpp} | 14 +++++----- .../model/table/{HederaIds.h => HederaId.h} | 6 ++-- .../{HederaTopics.cpp => HederaTopic.cpp} | 14 +++++----- .../table/{HederaTopics.h => HederaTopic.h} | 6 ++-- src/cpp/model/table/User.cpp | 4 +-- src/cpp/model/table/User.h | 2 +- .../table/{UserBackups.cpp => UserBackup.cpp} | 24 ++++++++-------- .../table/{UserBackups.h => UserBackup.h} | 10 +++---- .../table/{UserRoles.cpp => UserRole.cpp} | 24 ++++++++-------- .../model/table/{UserRoles.h => UserRole.h} | 10 +++---- src/cpsp/adminCheckUserBackup.cpsp | 4 +-- src/cpsp/adminUserPasswordReset.cpsp | 2 +- src/cpsp/repairDefectPassphrase.cpsp | 2 +- 29 files changed, 147 insertions(+), 131 deletions(-) create mode 100644 doc/.gitignore rename src/cpp/controller/{UserBackups.cpp => UserBackup.cpp} (70%) rename src/cpp/controller/{UserBackups.h => UserBackup.h} (68%) rename src/cpp/model/table/{CryptoKeys.cpp => CryptoKey.cpp} (75%) rename src/cpp/model/table/{CryptoKeys.h => CryptoKey.h} (92%) rename src/cpp/model/table/{Groups.cpp => Group.cpp} (73%) rename src/cpp/model/table/{Groups.h => Group.h} (91%) rename src/cpp/model/table/{HederaAccounts.cpp => HederaAccount.cpp} (66%) rename src/cpp/model/table/{HederaAccounts.h => HederaAccount.h} (72%) rename src/cpp/model/table/{HederaIds.cpp => HederaId.cpp} (74%) rename src/cpp/model/table/{HederaIds.h => HederaId.h} (91%) rename src/cpp/model/table/{HederaTopics.cpp => HederaTopic.cpp} (84%) rename src/cpp/model/table/{HederaTopics.h => HederaTopic.h} (92%) rename src/cpp/model/table/{UserBackups.cpp => UserBackup.cpp} (78%) rename src/cpp/model/table/{UserBackups.h => UserBackup.h} (88%) rename src/cpp/model/table/{UserRoles.cpp => UserRole.cpp} (73%) rename src/cpp/model/table/{UserRoles.h => UserRole.h} (90%) diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 000000000..1936cc1d4 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +html diff --git a/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp b/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp index 940d084bc..c2ebcd232 100644 --- a/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp +++ b/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp @@ -10,7 +10,7 @@ #include "../Crypto/KeyPair.h" #include "../SingletonManager/ConnectionManager.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "Poco/Data/Binding.h" using namespace Poco::Data::Keywords; @@ -20,7 +20,7 @@ typedef Poco::Tuple, std::string> UserBack struct SListEntry { Poco::AutoPtr user; - std::vector> backups; + std::vector> backups; }; #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" @@ -94,7 +94,7 @@ void AdminCheckUserBackup::handleRequest(Poco::Net::HTTPServerRequest& request, SListEntry entry; entry.user = controller::User::create(); entry.user->load(user_id); - entry.backups = controller::UserBackups::load(user_id); + entry.backups = controller::UserBackup::load(user_id); notMatchingEntrys.push_back(entry); diff --git a/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp index 42778fd45..71a2f1bb0 100644 --- a/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp +++ b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp @@ -10,7 +10,7 @@ // includes #include "../controller/User.h" #include "../controller/EmailVerificationCode.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" enum PageState @@ -43,7 +43,7 @@ void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request PageState state = PAGE_ASK_EMAIL; Poco::AutoPtr user = controller::User::create(); Poco::AutoPtr code; - Poco::AutoPtr userBackup; + Poco::AutoPtr userBackup; bool validUser = false; std::string pageName = "Admin User Passwort Reset"; @@ -69,7 +69,7 @@ void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request } } - auto backups = controller::UserBackups::load(userId); + auto backups = controller::UserBackup::load(userId); auto userPubkey = user->getModel()->getPublicKey(); for(auto it = backups.begin(); it != backups.end(); it++) { auto keys = (*it)->getKeyPair(); @@ -235,7 +235,7 @@ void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "Bitte schreibe sie dir auf und packe sie gut weg.\n"; responseStream << "\n"; #line 105 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" - responseStream << ( controller::UserBackups::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) ); + responseStream << ( controller::UserBackup::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) ); responseStream << "\n"; responseStream << " \n"; responseStream << "\n"; diff --git a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp index 3b8087c0c..77fd06514 100644 --- a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp +++ b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp @@ -13,7 +13,7 @@ #include "../Crypto/Passphrase.h" #include "../Crypto/KeyPairEd25519.h" #include "../lib/DataTypeConverter.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "../tasks/SigningTransaction.h" #include "../ServerConfig.h" @@ -85,7 +85,7 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request else { mSession->setPassphrase(passphrase); - auto newPassphraseModel = controller::UserBackups::create( + auto newPassphraseModel = controller::UserBackup::create( user_model->getID(), passphrase->getString(), ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES diff --git a/src/cpp/HTTPInterface/ResetPassword.cpp b/src/cpp/HTTPInterface/ResetPassword.cpp index 23d6b8331..7d1bbd28e 100644 --- a/src/cpp/HTTPInterface/ResetPassword.cpp +++ b/src/cpp/HTTPInterface/ResetPassword.cpp @@ -11,7 +11,7 @@ #include "../SingletonManager/SessionManager.h" #include "../SingletonManager/EmailManager.h" #include "../controller/User.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" enum PageState { PAGE_EMAIL_ASK, diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 605f11087..f425da9e0 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -1,5 +1,5 @@ #include "User.h" -#include "UserBackups.h" +#include "UserBackup.h" #include "sodium.h" @@ -299,7 +299,7 @@ namespace controller { auto user_model = getModel(); if (user_model->getID() <= 0) return -2; - auto backups = UserBackups::load(user_model->getID()); + auto backups = UserBackup::load(user_model->getID()); if (backups.size() == 0) return -1; for (auto it = backups.begin(); it != backups.end(); it++) { auto user_backup = *it; diff --git a/src/cpp/controller/UserBackups.cpp b/src/cpp/controller/UserBackup.cpp similarity index 70% rename from src/cpp/controller/UserBackups.cpp rename to src/cpp/controller/UserBackup.cpp index bf7096442..9a152592f 100644 --- a/src/cpp/controller/UserBackups.cpp +++ b/src/cpp/controller/UserBackup.cpp @@ -1,14 +1,14 @@ -#include "UserBackups.h" +#include "UserBackup.h" #include "../Crypto/Passphrase.h" namespace controller { - UserBackups::UserBackups(model::table::UserBackups* dbModel) + UserBackup::UserBackup(model::table::UserBackup* dbModel) { mDBModel = dbModel; } - UserBackups::~UserBackups() + UserBackup::~UserBackup() { } @@ -17,20 +17,20 @@ namespace controller { // --------------- static members ----------------------------- - Poco::AutoPtr UserBackups::create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) + Poco::AutoPtr UserBackup::create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) { - auto db = new model::table::UserBackups(user_id, passphrase, type); - return Poco::AutoPtr(new UserBackups(db)); + auto db = new model::table::UserBackup(user_id, passphrase, type); + return Poco::AutoPtr(new UserBackup(db)); } - std::vector> UserBackups::load(int user_id) + std::vector> UserBackup::load(int user_id) { - auto db = new model::table::UserBackups(); + auto db = new model::table::UserBackup(); auto results = db->loadFromDB("user_id", user_id, 1); - std::vector> resultObjects; + std::vector> resultObjects; if (db->errorCount()) { db->sendErrorsAsEmail(); db->release(); @@ -41,14 +41,14 @@ namespace controller { return resultObjects; } for (auto it = results.begin(); it != results.end(); it++) { - resultObjects.push_back(new UserBackups(new model::table::UserBackups(*it))); + resultObjects.push_back(new UserBackup(new model::table::UserBackup(*it))); } return resultObjects; } - Poco::SharedPtr UserBackups::getKeyPair() + Poco::SharedPtr UserBackup::getKeyPair() { if (!mKeyPair.isNull()) { return mKeyPair; @@ -61,7 +61,7 @@ namespace controller { return mKeyPair; } - KeyPairEd25519* UserBackups::createGradidoKeyPair() + KeyPairEd25519* UserBackup::createGradidoKeyPair() { auto model = getModel(); auto mnemonicType = model->getMnemonicType(); @@ -71,7 +71,7 @@ namespace controller { return KeyPairEd25519::create(passphrase); } - std::string UserBackups::getPassphrase(ServerConfig::Mnemonic_Types type) + std::string UserBackup::getPassphrase(ServerConfig::Mnemonic_Types type) { if ((int)type < 0 || (int)type >= ServerConfig::Mnemonic_Types::MNEMONIC_MAX) { return ""; @@ -96,7 +96,7 @@ namespace controller { } - std::string UserBackups::formatPassphrase(std::string passphrase, int targetLinesCount/* = 5*/) + std::string UserBackup::formatPassphrase(std::string passphrase, int targetLinesCount/* = 5*/) { int count = passphrase.size(); int charPerLine = count / (targetLinesCount); diff --git a/src/cpp/controller/UserBackups.h b/src/cpp/controller/UserBackup.h similarity index 68% rename from src/cpp/controller/UserBackups.h rename to src/cpp/controller/UserBackup.h index c1cb08047..a21d1c3ab 100644 --- a/src/cpp/controller/UserBackups.h +++ b/src/cpp/controller/UserBackup.h @@ -1,7 +1,7 @@ #ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE #define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE -#include "../model/table/UserBackups.h" +#include "../model/table/UserBackup.h" #include "../Crypto/KeyPair.h" #include "../Crypto/KeyPairEd25519.h" @@ -10,19 +10,19 @@ #include "TableControllerBase.h" namespace controller { - class UserBackups : public TableControllerBase + class UserBackup : public TableControllerBase { public: - ~UserBackups(); + ~UserBackup(); - static Poco::AutoPtr create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); + static Poco::AutoPtr create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); - static std::vector> load(int user_id); + static std::vector> load(int user_id); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } - inline Poco::AutoPtr getModel() { return _getModel(); } + inline Poco::AutoPtr getModel() { return _getModel(); } //! depracted //! \return create keyPair from passphrase if not exist, else return existing pointer @@ -37,7 +37,7 @@ namespace controller { std::string getPassphrase(ServerConfig::Mnemonic_Types type); protected: - UserBackups(model::table::UserBackups* dbModel); + UserBackup(model::table::UserBackup* dbModel); Poco::SharedPtr mKeyPair; }; diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 463241fcd..2e24e8610 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -24,7 +24,7 @@ #include "../controller/User.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "../controller/EmailVerificationCode.h" #include "table/ModelBase.h" @@ -777,7 +777,7 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo if (-2 == loginResult) { // check if we have access to the passphrase, if so we can reencrypt the private key auto user_model = mNewUser->getModel(); - auto user_backups = controller::UserBackups::load(user_model->getID()); + auto user_backups = controller::UserBackup::load(user_model->getID()); for (auto it = user_backups.begin(); it != user_backups.end(); it++) { auto key = std::unique_ptr((*it)->createGradidoKeyPair()); if (key->isTheSame(user_model->getPublicKey())) @@ -941,7 +941,7 @@ void Session::detectSessionState() if (USER_NO_KEYS == userState) { auto user_id = mSessionUser->getDBId(); - auto userBackups = controller::UserBackups::load(user_id); + auto userBackups = controller::UserBackup::load(user_id); // check passphrase, only possible while passphrase isn't crypted in db bool correctPassphraseFound = false; @@ -1157,7 +1157,7 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase) } if (savePassphrase) { - auto user_backup = controller::UserBackups::create(user_model->getID(), passphrase->getString(), mnemonic_type); + auto user_backup = controller::UserBackup::create(user_model->getID(), passphrase->getString(), mnemonic_type); // sync version //user_backup->getModel()->insertIntoDB(false); diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index 27539ecf1..80763d337 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -12,7 +12,7 @@ #include "../SingletonManager/LanguageManager.h" #include "../SingletonManager/SingletonTaskObserver.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "Poco/Data/Binding.h" @@ -1090,7 +1090,7 @@ MemoryBin* User::sign(const unsigned char* message, size_t messageSize) //addError(new Error("User::sign", "decrypt privkey failed")); - auto userBackups = controller::UserBackups::load(mDBId); + auto userBackups = controller::UserBackup::load(mDBId); // get privkey, only possible while passphrase isn't crypted in db bool correctPassphraseFound = false; diff --git a/src/cpp/model/table/CryptoKeys.cpp b/src/cpp/model/table/CryptoKey.cpp similarity index 75% rename from src/cpp/model/table/CryptoKeys.cpp rename to src/cpp/model/table/CryptoKey.cpp index e159f51cc..201047a5b 100644 --- a/src/cpp/model/table/CryptoKeys.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -1,20 +1,20 @@ -#include "CryptoKeys.h" +#include "CryptoKey.h" #include "../../lib/DataTypeConverter.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - CryptoKeys::CryptoKeys() + CryptoKey::CryptoKey() { } - CryptoKeys::~CryptoKeys() + CryptoKey::~CryptoKey() { } - std::string CryptoKeys::toString() + std::string CryptoKey::toString() { assert(mKeyType < KEY_TYPE_COUNT && mKeyType >= 0); std::stringstream ss; @@ -24,7 +24,7 @@ namespace model { } - const char* CryptoKeys::typeToString(KeyType type) + const char* CryptoKey::typeToString(KeyType type) { switch (type) { case KEY_TYPE_ED25519_REF10: return "ed25519 ref10"; @@ -33,7 +33,7 @@ namespace model { return ""; } - Poco::Data::Statement CryptoKeys::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -44,7 +44,7 @@ namespace model { return select; } - Poco::Data::Statement CryptoKeys::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement CryptoKey::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -56,7 +56,7 @@ namespace model { } - Poco::Data::Statement CryptoKeys::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement CryptoKey::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/CryptoKeys.h b/src/cpp/model/table/CryptoKey.h similarity index 92% rename from src/cpp/model/table/CryptoKeys.h rename to src/cpp/model/table/CryptoKey.h index 15991c70b..1a04dd387 100644 --- a/src/cpp/model/table/CryptoKeys.h +++ b/src/cpp/model/table/CryptoKey.h @@ -13,11 +13,11 @@ namespace model { KEY_TYPE_COUNT }; - class CryptoKeys : public ModelBase + class CryptoKey : public ModelBase { public: - CryptoKeys(); - ~CryptoKeys(); + CryptoKey(); + ~CryptoKey(); // generic db operations const char* getTableName() const { return "crypto_keys"; } diff --git a/src/cpp/model/table/Groups.cpp b/src/cpp/model/table/Group.cpp similarity index 73% rename from src/cpp/model/table/Groups.cpp rename to src/cpp/model/table/Group.cpp index e99780783..458f8f0dd 100644 --- a/src/cpp/model/table/Groups.cpp +++ b/src/cpp/model/table/Group.cpp @@ -1,19 +1,19 @@ -#include "Groups.h" +#include "Group.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - Groups::Groups() + Group::Group() { } - Groups::~Groups() + Group::~Group() { } - std::string Groups::toString() + std::string Group::toString() { std::stringstream ss; ss << "Alias: " << mAlias << std::endl; @@ -22,7 +22,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement Groups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement Group::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -32,7 +32,7 @@ namespace model { return select; } - Poco::Data::Statement Groups::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement Group::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -43,7 +43,7 @@ namespace model { return select; } - Poco::Data::Statement Groups::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement Group::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/Groups.h b/src/cpp/model/table/Group.h similarity index 91% rename from src/cpp/model/table/Groups.h rename to src/cpp/model/table/Group.h index adc5789c0..bde1b0d68 100644 --- a/src/cpp/model/table/Groups.h +++ b/src/cpp/model/table/Group.h @@ -6,11 +6,11 @@ namespace model { namespace table { - class Groups : public ModelBase + class Group : public ModelBase { public: - Groups(); - ~Groups(); + Group(); + ~Group(); // generic db operations const char* getTableName() const { return "groups"; } diff --git a/src/cpp/model/table/HederaAccounts.cpp b/src/cpp/model/table/HederaAccount.cpp similarity index 66% rename from src/cpp/model/table/HederaAccounts.cpp rename to src/cpp/model/table/HederaAccount.cpp index 3c019374d..4018c653a 100644 --- a/src/cpp/model/table/HederaAccounts.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -1,21 +1,21 @@ -#include "HederaAccounts.h" +#include "HederaAccount.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - HederaAccounts::HederaAccounts() + HederaAccount::HederaAccount() { } - HederaAccounts::~HederaAccounts() + HederaAccount::~HederaAccount() { } - std::string HederaAccounts::toString() + std::string HederaAccount::toString() { std::stringstream ss; ss << "user id: " << std::to_string(mUserId) << std::endl; @@ -28,7 +28,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement HederaAccounts::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -39,7 +39,16 @@ namespace model { return select; } - Poco::Data::Statement HederaAccounts::_loadIdFromDB(Poco::Data::Session session) + + Poco::Data::Statement HederaAccount::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + << " where " << fieldName << " LIKE ?"; + + return select; + } + Poco::Data::Statement HederaAccount::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -49,7 +58,7 @@ namespace model { unlock(); return select; } - Poco::Data::Statement HederaAccounts::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement HederaAccount::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); @@ -59,5 +68,7 @@ namespace model { unlock(); return insert; } + + } } \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccounts.h b/src/cpp/model/table/HederaAccount.h similarity index 72% rename from src/cpp/model/table/HederaAccounts.h rename to src/cpp/model/table/HederaAccount.h index 74b2063d4..c9c85b554 100644 --- a/src/cpp/model/table/HederaAccounts.h +++ b/src/cpp/model/table/HederaAccount.h @@ -2,15 +2,18 @@ #define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE #include "ModelBase.h" +#include "Poco/Tuple.h" namespace model { namespace table { - class HederaAccounts : public ModelBase + typedef Poco::Tuple HederaAccountsTuple; + + class HederaAccount : public ModelBase { public: - HederaAccounts(); - ~HederaAccounts(); + HederaAccount(); + ~HederaAccount(); // generic db operations const char* getTableName() const { return "hedera_accounts"; } @@ -19,6 +22,7 @@ namespace model { protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); diff --git a/src/cpp/model/table/HederaIds.cpp b/src/cpp/model/table/HederaId.cpp similarity index 74% rename from src/cpp/model/table/HederaIds.cpp rename to src/cpp/model/table/HederaId.cpp index 8eeed0e55..b048a0d71 100644 --- a/src/cpp/model/table/HederaIds.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -1,20 +1,20 @@ -#include "HederaIds.h" +#include "HederaId.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - HederaIds::HederaIds() + HederaId::HederaId() { } - HederaIds::~HederaIds() + HederaId::~HederaId() { } - std::string HederaIds::toString() + std::string HederaId::toString() { std::stringstream ss; ss << "Shard Num: " << std::to_string(mShardNum) << std::endl; @@ -23,7 +23,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement HederaIds::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -34,7 +34,7 @@ namespace model { return select; } - Poco::Data::Statement HederaIds::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement HederaId::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -44,7 +44,7 @@ namespace model { unlock(); return select; } - Poco::Data::Statement HederaIds::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement HederaId::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/HederaIds.h b/src/cpp/model/table/HederaId.h similarity index 91% rename from src/cpp/model/table/HederaIds.h rename to src/cpp/model/table/HederaId.h index eaa6612b8..ef35b2e70 100644 --- a/src/cpp/model/table/HederaIds.h +++ b/src/cpp/model/table/HederaId.h @@ -7,11 +7,11 @@ namespace model { namespace table { - class HederaIds : public ModelBase + class HederaId : public ModelBase { public: - HederaIds(); - ~HederaIds(); + HederaId(); + ~HederaId(); // generic db operations const char* getTableName() const { return "hedera_ids"; } diff --git a/src/cpp/model/table/HederaTopics.cpp b/src/cpp/model/table/HederaTopic.cpp similarity index 84% rename from src/cpp/model/table/HederaTopics.cpp rename to src/cpp/model/table/HederaTopic.cpp index aeed1ea05..ef80ea071 100644 --- a/src/cpp/model/table/HederaTopics.cpp +++ b/src/cpp/model/table/HederaTopic.cpp @@ -1,20 +1,20 @@ -#include "HederaTopics.h" +#include "HederaTopic.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - HederaTopics::HederaTopics() + HederaTopic::HederaTopic() { } - HederaTopics::~HederaTopics() + HederaTopic::~HederaTopic() { } - std::string HederaTopics::toString() + std::string HederaTopic::toString() { std::stringstream ss; ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl; @@ -29,7 +29,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement HederaTopics::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement HederaTopic::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -42,7 +42,7 @@ namespace model { return select; } - Poco::Data::Statement HederaTopics::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement HederaTopic::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -52,7 +52,7 @@ namespace model { unlock(); return select; } - Poco::Data::Statement HederaTopics::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement HederaTopic::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/HederaTopics.h b/src/cpp/model/table/HederaTopic.h similarity index 92% rename from src/cpp/model/table/HederaTopics.h rename to src/cpp/model/table/HederaTopic.h index 4584026ab..fe5cc342b 100644 --- a/src/cpp/model/table/HederaTopics.h +++ b/src/cpp/model/table/HederaTopic.h @@ -6,11 +6,11 @@ namespace model { namespace table { - class HederaTopics : public ModelBase + class HederaTopic : public ModelBase { public: - HederaTopics(); - ~HederaTopics(); + HederaTopic(); + ~HederaTopic(); // generic db operations const char* getTableName() const { return "hedera_topics"; } diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index e6f694c71..745982a25 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -315,7 +315,7 @@ namespace model { ss << "created: " << Poco::DateTimeFormatter::format(mCreated, "%f.%m.%Y %H:%M:%S") << "
"; ss << "email checked: " << mEmailChecked << "
"; ss << "language key: " << mLanguageKey << "
"; - ss << "role: " << UserRoles::typeToString(getRole()) << "
"; + ss << "role: " << UserRole::typeToString(getRole()) << "
"; ss << "disabled: " << mDisabled << "
"; mm->releaseMemory(pubkeyHex); @@ -357,7 +357,7 @@ namespace model { userObj.set("ident_hash", DRMakeStringHash(mEmail.data(), mEmail.size())); userObj.set("disabled", mDisabled); try { - userObj.set("role", UserRoles::typeToString(getRole())); + userObj.set("role", UserRole::typeToString(getRole())); } catch (Poco::Exception ex) { addError(new ParamError("User::getJson", "exception by getting role", ex.displayText().data())); diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index 7f8e35c0a..5fb9de668 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -11,7 +11,7 @@ #include -#include "UserRoles.h" +#include "UserRole.h" namespace model { namespace table { diff --git a/src/cpp/model/table/UserBackups.cpp b/src/cpp/model/table/UserBackup.cpp similarity index 78% rename from src/cpp/model/table/UserBackups.cpp rename to src/cpp/model/table/UserBackup.cpp index 0dbf0adfa..e45a78066 100644 --- a/src/cpp/model/table/UserBackups.cpp +++ b/src/cpp/model/table/UserBackup.cpp @@ -1,4 +1,4 @@ -#include "UserBackups.h" +#include "UserBackup.h" #include "../../controller/User.h" using namespace Poco::Data::Keywords; @@ -6,31 +6,31 @@ using namespace Poco::Data::Keywords; namespace model { namespace table { - UserBackups::UserBackups() + UserBackup::UserBackup() : mUserId(0), mMnemonicType(0) { detectMnemonic(); } - UserBackups::UserBackups(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) + UserBackup::UserBackup(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) : mUserId(user_id), mPassphrase(passphrase), mMnemonicType(type) { detectMnemonic(); } - UserBackups::UserBackups(const UserBackupsTuple& tuple) + UserBackup::UserBackup(const UserBackupsTuple& tuple) : ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mPassphrase(tuple.get<2>()), mMnemonicType(tuple.get<3>()) { detectMnemonic(); } - UserBackups::~UserBackups() + UserBackup::~UserBackup() { } - Poco::Data::Statement UserBackups::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement UserBackup::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); @@ -43,7 +43,7 @@ namespace model { } - Poco::Data::Statement UserBackups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserBackup::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -55,7 +55,7 @@ namespace model { return select; } - Poco::Data::Statement UserBackups::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement UserBackup::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); @@ -66,7 +66,7 @@ namespace model { return select; } - Poco::Data::Statement UserBackups::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserBackup::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -77,7 +77,7 @@ namespace model { return select; } - Poco::Data::Statement UserBackups::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) + Poco::Data::Statement UserBackup::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) { Poco::Data::Statement select(session); if (fieldNames.size() <= 1) { @@ -107,7 +107,7 @@ namespace model { } // generic db operations - std::string UserBackups::toString() + std::string UserBackup::toString() { std::stringstream ss; ss << "user_id: " << mUserId << std::endl; @@ -116,7 +116,7 @@ namespace model { return ss.str(); } - void UserBackups::detectMnemonic() + void UserBackup::detectMnemonic() { if (mMnemonicType == -1) { const static char* function_name = "UserBackups::detectMnemonic"; diff --git a/src/cpp/model/table/UserBackups.h b/src/cpp/model/table/UserBackup.h similarity index 88% rename from src/cpp/model/table/UserBackups.h rename to src/cpp/model/table/UserBackup.h index d307f8f5d..c5084b0f7 100644 --- a/src/cpp/model/table/UserBackups.h +++ b/src/cpp/model/table/UserBackup.h @@ -9,13 +9,13 @@ namespace model { typedef Poco::Tuple UserBackupsTuple; - class UserBackups : public ModelBase + class UserBackup : public ModelBase { public: - UserBackups(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); - UserBackups(const UserBackupsTuple& tuple); - UserBackups(); - ~UserBackups(); + UserBackup(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); + UserBackup(const UserBackupsTuple& tuple); + UserBackup(); + ~UserBackup(); // generic db operations const char* getTableName() const { return "user_backups"; } diff --git a/src/cpp/model/table/UserRoles.cpp b/src/cpp/model/table/UserRole.cpp similarity index 73% rename from src/cpp/model/table/UserRoles.cpp rename to src/cpp/model/table/UserRole.cpp index 0d1f673e9..28e314606 100644 --- a/src/cpp/model/table/UserRoles.cpp +++ b/src/cpp/model/table/UserRole.cpp @@ -1,4 +1,4 @@ -#include "UserRoles.h" +#include "UserRole.h" using namespace Poco::Data::Keywords; @@ -6,28 +6,28 @@ namespace model { namespace table { - UserRoles::UserRoles(int user_id, RoleType type) + UserRole::UserRole(int user_id, RoleType type) : mUserId(user_id), mType(type) { } - UserRoles::UserRoles(const UserRolesTuple& tuple) + UserRole::UserRole(const UserRolesTuple& tuple) : ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mType(tuple.get<2>()) { } - UserRoles::UserRoles() + UserRole::UserRole() { } - UserRoles::~UserRoles() + UserRole::~UserRole() { } - Poco::Data::Statement UserRoles::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement UserRole::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); @@ -40,7 +40,7 @@ namespace model { } - Poco::Data::Statement UserRoles::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserRole::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -52,7 +52,7 @@ namespace model { return select; } - Poco::Data::Statement UserRoles::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement UserRole::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); @@ -63,7 +63,7 @@ namespace model { return select; } - Poco::Data::Statement UserRoles::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserRole::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -74,7 +74,7 @@ namespace model { return select; } - Poco::Data::Statement UserRoles::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) + Poco::Data::Statement UserRole::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) { Poco::Data::Statement select(session); if (fieldNames.size() <= 1) { @@ -104,7 +104,7 @@ namespace model { } // generic db operations - std::string UserRoles::toString() + std::string UserRole::toString() { std::stringstream ss; ss << "user_id: " << mUserId << std::endl; @@ -112,7 +112,7 @@ namespace model { return ss.str(); } - const char* UserRoles::typeToString(RoleType type) + const char* UserRole::typeToString(RoleType type) { switch (type) { case ROLE_NOT_LOADED: return "not loaded"; diff --git a/src/cpp/model/table/UserRoles.h b/src/cpp/model/table/UserRole.h similarity index 90% rename from src/cpp/model/table/UserRoles.h rename to src/cpp/model/table/UserRole.h index 7b3fad790..7683bff94 100644 --- a/src/cpp/model/table/UserRoles.h +++ b/src/cpp/model/table/UserRole.h @@ -17,13 +17,13 @@ namespace model { typedef Poco::Tuple UserRolesTuple; - class UserRoles : public ModelBase + class UserRole : public ModelBase { public: - UserRoles(int user_id, RoleType type); - UserRoles(const UserRolesTuple& tuple); - UserRoles(); - ~UserRoles(); + UserRole(int user_id, RoleType type); + UserRole(const UserRolesTuple& tuple); + UserRole(); + ~UserRole(); // generic db operations const char* getTableName() const { return "user_roles"; } diff --git a/src/cpsp/adminCheckUserBackup.cpsp b/src/cpsp/adminCheckUserBackup.cpsp index bca35b05a..35ac38ad4 100644 --- a/src/cpsp/adminCheckUserBackup.cpsp +++ b/src/cpsp/adminCheckUserBackup.cpsp @@ -18,7 +18,7 @@ typedef Poco::Tuple, std::string> UserBack struct SListEntry { Poco::AutoPtr user; - std::vector> backups; + std::vector> backups; }; %> @@ -73,7 +73,7 @@ struct SListEntry SListEntry entry; entry.user = controller::User::create(); entry.user->load(user_id); - entry.backups = controller::UserBackups::load(user_id); + entry.backups = controller::UserBackup::load(user_id); notMatchingEntrys.push_back(entry); diff --git a/src/cpsp/adminUserPasswordReset.cpsp b/src/cpsp/adminUserPasswordReset.cpsp index 648a18f61..f534b8c4d 100644 --- a/src/cpsp/adminUserPasswordReset.cpsp +++ b/src/cpsp/adminUserPasswordReset.cpsp @@ -21,7 +21,7 @@ enum PageState PageState state = PAGE_ASK_EMAIL; Poco::AutoPtr user = controller::User::create(); Poco::AutoPtr code; - Poco::AutoPtr userBackup; + Poco::AutoPtr userBackup; bool validUser = false; std::string pageName = "Admin User Passwort Reset"; diff --git a/src/cpsp/repairDefectPassphrase.cpsp b/src/cpsp/repairDefectPassphrase.cpsp index fc9eba7fd..0e8c82e64 100644 --- a/src/cpsp/repairDefectPassphrase.cpsp +++ b/src/cpsp/repairDefectPassphrase.cpsp @@ -64,7 +64,7 @@ enum PageState else { mSession->setPassphrase(passphrase); - auto newPassphraseModel = controller::UserBackups::create( + auto newPassphraseModel = controller::UserBackup::create( user_model->getID(), passphrase->getString(), ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES From f817374c463eb3af295642c9ec0ae1d6ba70dd8c Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 27 Aug 2020 08:35:18 +0200 Subject: [PATCH 009/195] add groups page for listing and add groups (only for admins) --- skeema/gradido_login/groups.sql | 1 + skeema/gradido_login/hedera_topics.sql | 2 +- src/cpp/HTTPInterface/AdminGroupsPage.cpp | 212 ++++++++++++++++++ src/cpp/HTTPInterface/AdminGroupsPage.h | 20 ++ .../PageRequestHandlerFactory.cpp | 6 + src/cpp/controller/Group.cpp | 69 ++++++ src/cpp/controller/Group.h | 33 +++ src/cpp/model/table/Group.cpp | 41 +++- src/cpp/model/table/Group.h | 19 +- src/cpp/model/table/ModelBase.cpp | 7 + src/cpp/model/table/ModelBase.h | 26 +++ src/cpsp/adminGroups.cpsp | 80 +++++++ 12 files changed, 510 insertions(+), 6 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminGroupsPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminGroupsPage.h create mode 100644 src/cpp/controller/Group.cpp create mode 100644 src/cpp/controller/Group.h create mode 100644 src/cpsp/adminGroups.cpsp diff --git a/skeema/gradido_login/groups.sql b/skeema/gradido_login/groups.sql index 8c5e143bb..7d4c5a185 100644 --- a/skeema/gradido_login/groups.sql +++ b/skeema/gradido_login/groups.sql @@ -2,6 +2,7 @@ CREATE TABLE `groups` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `alias` varchar(190) NOT NULL, `name` varchar(255) NOT NULL, + `url` varchar(255) NOT NULL, `description` text, PRIMARY KEY (`id`), UNIQUE KEY `alias` (`alias`) diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index 6a58174c1..02f7e3b39 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -6,7 +6,7 @@ CREATE TABLE `hedera_topics` ( `group_id` int unsigned NOT NULL, `admin_key_id` int unsigned DEFAULT NULL, `submit_key_id` int unsigned DEFAULT NULL, - `current_timeout` timestamp NOT NULL DEFAULT '0', + `current_timeout` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', `sequence_number` bigint unsigned DEFAULT '0', `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), diff --git a/src/cpp/HTTPInterface/AdminGroupsPage.cpp b/src/cpp/HTTPInterface/AdminGroupsPage.cpp new file mode 100644 index 000000000..1e6619801 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminGroupsPage.cpp @@ -0,0 +1,212 @@ +#include "AdminGroupsPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + + #include "../controller/Group.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + +#include "../ServerConfig.h" + + +AdminGroupsPage::AdminGroupsPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + + const char* pageName = "Gruppen"; + + // add + if(!form.empty()) { + auto alias = form.get("group-alias"); + if(alias == "") + { + addError(new Error("Add Group", "Alias is empty!")); + } + else + { + auto newGroup = controller::Group::create( + alias, + form.get("group-name", ""), + form.get("group-url", ""), + form.get("group-desc", "") + ); + newGroup->getModel()->insertIntoDB(false); + } + } + + // select all + auto groups = controller::Group::listAll(); + //auto groups = controller::Group::load("gdd1"); + //std::vector> groups; + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << " "; + // end include header.cpsp + responseStream << "\n"; +#line 38 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

Alle Gruppen

\n"; + responseStream << "\t\t
\t\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t
ID
\n"; + responseStream << "\t\t\t\t
Name
\n"; + responseStream << "\t\t\t\t
Alias
\n"; + responseStream << "\t\t\t\t
Url
\n"; + responseStream << "\t\t\t\t
"; +#line 50 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( gettext("Description") ); + responseStream << "
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t"; +#line 52 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t
"; +#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getID() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getName() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 57 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getAlias() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 58 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getUrl() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getDescription()); + responseStream << "
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t"; +#line 61 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + } responseStream << "\n"; + responseStream << "\t\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t

Eine neue Gruppe anlegen

\n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t
\n"; + responseStream << "
\n"; + // begin include footer.cpsp + responseStream << "
\n"; + responseStream << "

Copyright © Gradido 2020

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "

Login Server in Entwicklung

\n"; + responseStream << "

Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminGroupsPage.h b/src/cpp/HTTPInterface/AdminGroupsPage.h new file mode 100644 index 000000000..43a99ffb4 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminGroupsPage.h @@ -0,0 +1,20 @@ +#ifndef AdminGroupsPage_INCLUDED +#define AdminGroupsPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminGroupsPage: public SessionHTTPRequestHandler +{ +public: + AdminGroupsPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminGroupsPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 454cc930a..50dc610af 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -27,6 +27,7 @@ #include "PassphrasedTransaction.h" #include "AdminUserPasswordReset.h" #include "RegisterDirectPage.h" +#include "AdminGroupsPage.h" #include "DecodeTransactionPage.h" #include "RepairDefectPassphrase.h" @@ -206,6 +207,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/groups") { + auto pageRequestHandler = new AdminGroupsPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/controller/Group.cpp b/src/cpp/controller/Group.cpp new file mode 100644 index 000000000..d5b3eb2ba --- /dev/null +++ b/src/cpp/controller/Group.cpp @@ -0,0 +1,69 @@ + +#include "Group.h" + +namespace controller { + + Group::Group(model::table::Group* dbModel) + { + mDBModel = dbModel; + } + + Group::~Group() + { + + } + + Poco::AutoPtr Group::create(const std::string& alias, const std::string& name, const std::string& url, const std::string& description) + { + auto db = new model::table::Group(alias, name, url, description); + auto group = new Group(db); + return Poco::AutoPtr(group); + } + + std::vector> Group::load(const std::string& alias) + { + auto db = new model::table::Group(); + auto group_list = db->loadFromDB("alias", alias, 0); + + std::vector> resultVector; + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + resultVector.push_back(new Group(new model::table::Group(*it))); + } + return resultVector; + } + + std::vector> Group::listAll() + { + auto db = new model::table::Group(); + std::vector group_list; + // throw an unresolved external symbol error + //group_list = db->loadAllFromDB(); + + // work around for not working call to loadAllFromDB + auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + + select << "SELECT id, alias, name, url, description FROM " << db->getTableName() + , Poco::Data::Keywords::into(group_list); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + } + catch (Poco::Exception& ex) { + printf("[Group::listAll] poco exception: %s\n", ex.displayText().data()); + } + // work around end + std::vector> resultVector; + + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + Poco::AutoPtr group_ptr(new Group(new model::table::Group(*it))); + resultVector.push_back(group_ptr); + } + return resultVector; + } + +} + diff --git a/src/cpp/controller/Group.h b/src/cpp/controller/Group.h new file mode 100644 index 000000000..e1ff29b64 --- /dev/null +++ b/src/cpp/controller/Group.h @@ -0,0 +1,33 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_GROUP_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_GROUP_INCLUDE + +#include "../model/table/Group.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + class Group : public TableControllerBase + { + public: + + ~Group(); + + static Poco::AutoPtr create(const std::string& alias, const std::string& name, const std::string& url, const std::string& description); + + static std::vector> load(const std::string& alias); + static std::vector> listAll(); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + Group(model::table::Group* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_GROUP_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/Group.cpp b/src/cpp/model/table/Group.cpp index 458f8f0dd..c1a84e832 100644 --- a/src/cpp/model/table/Group.cpp +++ b/src/cpp/model/table/Group.cpp @@ -8,6 +8,19 @@ namespace model { { } + Group::Group(const std::string& alias, const std::string& name, const std::string& url, const std::string& description) + : mAlias(alias), mName(name), mUrl(url), mDescription(description) + { + + } + + Group::Group(GroupTuple tuple) + : ModelBase(tuple.get<0>()), + mAlias(tuple.get<1>()), mName(tuple.get<2>()), mUrl(tuple.get<3>()), mDescription(tuple.get<4>()) + { + + } + Group::~Group() { @@ -18,6 +31,7 @@ namespace model { std::stringstream ss; ss << "Alias: " << mAlias << std::endl; ss << "Name: " << mName << std::endl; + ss << "Url: " << mUrl << std::endl; ss << "Description:" << mDescription << std::endl; return ss.str(); } @@ -26,9 +40,28 @@ namespace model { { Poco::Data::Statement select(session); - select << "SELECT id, alias, name, description FROM " << getTableName() + select << "SELECT id, alias, name, url, description FROM " << getTableName() << " where " << fieldName << " = ?" - , into(mID), into(mAlias), into(mName), into(mDescription); + , into(mID), into(mAlias), into(mName), into(mUrl), into(mDescription); + + return select; + } + + Poco::Data::Statement Group::_loadAllFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + + select << "SELECT id, alias, name, url, description FROM " << getTableName(); + + return select; + } + + Poco::Data::Statement Group::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + // typedef Poco::Tuple, int> UserTuple; + select << "SELECT id, alias, name, url, description FROM " << getTableName() + << " where " << fieldName << " LIKE ?"; return select; } @@ -48,8 +81,8 @@ namespace model { Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (alias, name, description) VALUES(?,?,?)" - , use(mAlias), use(mName), use(mDescription); + << " (alias, name, url, description) VALUES(?,?,?,?)" + , use(mAlias), use(mName), use(mUrl), use(mDescription); unlock(); return insert; } diff --git a/src/cpp/model/table/Group.h b/src/cpp/model/table/Group.h index bde1b0d68..1f6296b92 100644 --- a/src/cpp/model/table/Group.h +++ b/src/cpp/model/table/Group.h @@ -2,30 +2,47 @@ #define GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE #include "ModelBase.h" +#include "Poco/Tuple.h" namespace model { namespace table { + typedef Poco::Tuple GroupTuple; + class Group : public ModelBase { public: Group(); + Group(const std::string& alias, const std::string& name, const std::string& url, const std::string& description); + Group(GroupTuple userTuple); ~Group(); // generic db operations const char* getTableName() const { return "groups"; } std::string toString(); + inline const std::string& getAlias() const { return mAlias; } + inline const std::string& getName() const { std::shared_lock _lock(mSharedMutex); return mName; } + inline const std::string& getDescription() const { std::shared_lock _lock(mSharedMutex); return mDescription; } + inline const std::string& getUrl() const { std::shared_lock _lock(mSharedMutex); return mUrl; } + + inline void setName(const std::string& name) { std::unique_lock _lock(mSharedMutex); mName = name; } + inline void setDescription(const std::string& desc) { std::unique_lock _lock(mSharedMutex); mDescription = desc; } + inline void setUrl(const std::string& url) { std::unique_lock _lock(mSharedMutex); mUrl = url; } protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadAllFromDB(Poco::Data::Session session); + Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); - + std::string mAlias; std::string mName; + std::string mUrl; std::string mDescription; + mutable std::shared_mutex mSharedMutex; }; } diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index 5ba5a5529..4b55ea084 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -137,6 +137,13 @@ namespace model { throw Poco::Exception(message); } + Poco::Data::Statement ModelBase::_loadAllFromDB(Poco::Data::Session session) + { + std::string message = getTableName(); + message += "::_loadAllFromDB not implemented"; + throw Poco::Exception(message); + } + Poco::DateTime ModelBase::parseElopageDate(std::string dateString) { std::string decodedDateString = ""; diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 579fa8304..82e5c273e 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -42,6 +42,8 @@ namespace model { bool isExistInDB(const std::string& fieldName, const T& fieldValue); template std::vector loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0); + template + std::vector loadAllFromDB(); template size_t loadFromDB(const std::vector& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType = MYSQL_CONDITION_AND); template @@ -62,6 +64,7 @@ namespace model { virtual Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session) = 0; virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName) = 0; virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND); + virtual Poco::Data::Statement _loadAllFromDB(Poco::Data::Session session); virtual Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); virtual Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::vector fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND); virtual Poco::Data::Statement _insertIntoDB(Poco::Data::Session session) = 0; @@ -145,6 +148,29 @@ namespace model { return results; } + template + std::vector loadAllFromDB() + { + std::vector results; + Poco::ScopedLock _lock(mWorkMutex); + + auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select = _loadAllFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + select, Poco::Data::Keywords::into(results); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + } + catch (Poco::Exception& ex) { + lock(); + addError(new ParamError(getTableName(), "mysql error by selecting all", ex.displayText().data())); + unlock(); + } + + return results; + } + template std::vector ModelBase::loadFromDB(const std::vector& fieldNames, const std::vector& fieldValues, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/, int expectedResults/* = 0*/) { diff --git a/src/cpsp/adminGroups.cpsp b/src/cpsp/adminGroups.cpsp new file mode 100644 index 000000000..e357388af --- /dev/null +++ b/src/cpsp/adminGroups.cpsp @@ -0,0 +1,80 @@ +<%@ page class="AdminGroupsPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + #include "../controller/Group.h" +%> +<%% + const char* pageName = "Gruppen"; + + // add + if(!form.empty()) { + auto alias = form.get("group-alias"); + if(alias == "") + { + addError(new Error("Add Group", "Alias is empty!")); + } + else + { + auto newGroup = controller::Group::create( + alias, + form.get("group-name", ""), + form.get("group-url", ""), + form.get("group-desc", "") + ); + newGroup->getModel()->insertIntoDB(false); + } + } + + // select all + auto groups = controller::Group::listAll(); + //auto groups = controller::Group::load("gdd1"); + //std::vector> groups; + +%><%@ include file="header.cpsp" %> +<%= getErrorsHtml() %> +
+
+
+

Alle Gruppen

+
+
+
+
ID
+
Name
+
Alias
+
Url
+
<%= gettext("Description") %>
+
+ <% for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); %> +
+
<%= group_model->getID() %>
+
<%= group_model->getName() %>
+
<%= group_model->getAlias() %>
+
<%= group_model->getUrl() %>
+
<%= group_model->getDescription()%>
+
+ <% } %> +
+
+
+

Eine neue Gruppe anlegen

+
+
+
+ + + + + + + + + "> +
+
+<%@ include file="footer.cpsp" %> From 6a8c0d07254e3a6fb39306b016115dc2e1030b03 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:33:11 +0200 Subject: [PATCH 010/195] add KeyPairHedera mostly copied from KeyPairEd25519 but not testet yet. Maybe I must use the iroha ed25519 implementation because in the past sodium don't work together with hedera --- src/cpp/Crypto/KeyPairHedera.cpp | 148 +++++++++++++++++++++++++++++++ src/cpp/Crypto/KeyPairHedera.h | 82 +++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 src/cpp/Crypto/KeyPairHedera.cpp create mode 100644 src/cpp/Crypto/KeyPairHedera.h diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp new file mode 100644 index 000000000..80c4649b1 --- /dev/null +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -0,0 +1,148 @@ +#include "KeyPairHedera.h" +#include "../lib/DataTypeConverter.h" +#include + +#include "../SingletonManager/ErrorManager.h" + +KeyPairHedera::KeyPairHedera() + : mPrivateKey(nullptr) +{ + +} + + +KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) + : mPrivateKey(nullptr) +{ + auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420"); + auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100"); + + auto mm = MemoryManager::getInstance(); + + if (privateKey) { + switch (privateKey->size()) { + case 48: + // key with prefix + if (0 == sodium_memcmp(*privateKey, *derPrefixPriv, derPrefixPriv->size())) { + //int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed); + auto seed = mm->getFreeMemory(crypto_sign_ed25519_SEEDBYTES); + memcpy(*seed, privateKey->data(derPrefixPriv->size()), crypto_sign_ed25519_SEEDBYTES); + createKeyFromSeed(seed); + break; + } + case 32: + createKeyFromSeed(privateKey); + break; + case 64: + //mPrivateKey = privateKey; + if (!mPrivateKey || mPrivateKey->size() != privateKey->size()) { + if (mPrivateKey) { + mm->releaseMemory(mPrivateKey); + } + mPrivateKey = mm->getFreeMemory(privateKey->size()); + memcpy(*mPrivateKey, *privateKey, privateKey->size()); + } + break; + default: + throw std::exception("[KeyPairHedera] invalid private key"); + } + crypto_sign_ed25519_sk_to_pk(mPublicKey, *mPrivateKey); + } + else if (publicKey) { + switch (publicKey->size()) + { + case 32: { // raw public key + memcpy(mPublicKey, *publicKey, publicKey->size()); + break; + } + case 44: // DER encoded public key + if (0 == sodium_memcmp(*publicKey, *derPrefixPub, derPrefixPub->size())) { + memcpy(mPublicKey, publicKey->data(derPrefixPub->size()), ed25519_pubkey_SIZE); + } + break; + default: + throw std::exception("[KeyPairHedera] invalid public key"); + } + } + + + mm->releaseMemory(derPrefixPriv); + mm->releaseMemory(derPrefixPub); +} + +KeyPairHedera::~KeyPairHedera() +{ + auto mm = MemoryManager::getInstance(); + if (mPrivateKey) { + mm->releaseMemory(mPrivateKey); + mPrivateKey = nullptr; + } +} + + +void KeyPairHedera::createKeyFromSeed(const MemoryBin* seed) +{ + assert(seed && seed->size() == crypto_sign_ed25519_SEEDBYTES); + + auto mm = MemoryManager::getInstance(); + auto secret_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES); + crypto_sign_seed_keypair(mPublicKey, *secret_key, *seed); + + if (mPrivateKey) { + mm->releaseMemory(mPrivateKey); + } + mPrivateKey = secret_key; + + // iroha + //ed25519_privkey_SIZE + //ed25519_derive_public_key(const private_key_t* sk,public_key_t* pk); +} + +MemoryBin* KeyPairHedera::sign(const unsigned char* message, size_t messageSize) const +{ + if (!message || !messageSize) return nullptr; + if (!mPrivateKey) return nullptr; + auto mm = MemoryManager::getInstance(); + auto em = ErrorManager::getInstance(); + + const static char functionName[] = "KeyPairHedera::sign"; + + auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES); + unsigned long long actualSignLength = 0; + + if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *mPrivateKey)) { + em->addError(new Error(functionName, "sign failed")); + auto messageHex = DataTypeConverter::binToHex(message, messageSize); + em->addError(new ParamError(functionName, "message as hex", messageHex)); + mm->releaseMemory(signBinBuffer); + return nullptr; + } + + if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) { + // Incorrect signature! + //printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__); + em->addError(new Error(functionName, "sign verify failed")); + auto messageHex = DataTypeConverter::binToHex(message, messageSize); + em->addError(new ParamError(functionName, "message as hex", messageHex)); + mm->releaseMemory(signBinBuffer); + return nullptr; + } + + // debug + /*const size_t hex_sig_size = crypto_sign_BYTES * 2 + 1; + char sig_hex[hex_sig_size]; + sodium_bin2hex(sig_hex, hex_sig_size, *signBinBuffer, crypto_sign_BYTES); + printf("[User::sign] signature hex: %s\n", sig_hex); + */ + + return signBinBuffer; + +} + +bool KeyPairHedera::verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const +{ + if (crypto_sign_verify_detached(*signature, message, messageSize, mPublicKey) != 0) { + return false; + } + return true; +} \ No newline at end of file diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h new file mode 100644 index 000000000..358a3b680 --- /dev/null +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -0,0 +1,82 @@ +#ifndef __GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H +#define __GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H + +#include "IKeyPair.h" + +/*! +* \author: Dario Rekowski +* +* \date: 2020-08-28 +* +* \brief: Key Pairs class for ed25519 keys, used by hedera for transaction sign +*/ + + +#include "sodium.h" +#include "iroha-ed25519/include/ed25519/ed25519.h" + +class KeyPairHedera : public IKeyPair +{ +public: + //! \param privateKey: copy + //! \param publicKey: copy + //! + KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); + + ~KeyPairHedera(); + + + //! \return caller take ownership of return value + MemoryBin* sign(const MemoryBin* message) const { return sign(message->data(), message->size()); } + inline MemoryBin* sign(const std::string& bodyBytes) const { return sign((const unsigned char*)bodyBytes.data(), bodyBytes.size()); } + MemoryBin* sign(const unsigned char* message, size_t messageSize) const; + + bool verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const; + + inline const unsigned char* getPublicKey() const { return mPublicKey; } + + inline bool isTheSame(const KeyPairHedera& b) const { + return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); + } + inline bool isTheSame(const unsigned char* pubkey) const { + if (!pubkey) + return false; + return 0 == sodium_memcmp(mPublicKey, pubkey, ed25519_pubkey_SIZE); + } + //! \return 0 if the same + //! \return -1 if not the same + //! \return 1 if hasn't private key + inline int isTheSame(const MemoryBin* privkey) const { + if (!mPrivateKey) return 1; + if (privkey->size() != mPrivateKey->size()) return -1; + return sodium_memcmp(*mPrivateKey, *privkey, privkey->size()); + } + + inline bool operator == (const KeyPairHedera& b) const { return isTheSame(b); } + inline bool operator != (const KeyPairHedera& b) const { return !isTheSame(b); } + + inline bool operator == (const unsigned char* b) const { return isTheSame(b); } + inline bool operator != (const unsigned char* b) const { return !isTheSame(b); } + + inline bool hasPrivateKey() const { return mPrivateKey != nullptr; } + + + +protected: + + KeyPairHedera(); + void createKeyFromSeed(const MemoryBin* seed); + +private: + // 64 Byte + //! \brief ed25519 libsodium private key + //! + //! TODO: replace MemoryBin by a memory obfuscation class which make it hard to steal the private key from memory + MemoryBin* mPrivateKey; + + // 32 Byte + //! \brief ed25519 libsodium public key + unsigned char mPublicKey[ed25519_pubkey_SIZE]; +}; + +#endif //__GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H \ No newline at end of file From d8bb2d5c1e2c2ea02c16db8745ae4d595a66f08a Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:34:33 +0200 Subject: [PATCH 011/195] update comments, answer question --- src/cpp/Crypto/KeyPairEd25519.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpp/Crypto/KeyPairEd25519.h b/src/cpp/Crypto/KeyPairEd25519.h index 75a1ce9f1..08da7030d 100644 --- a/src/cpp/Crypto/KeyPairEd25519.h +++ b/src/cpp/Crypto/KeyPairEd25519.h @@ -9,6 +9,7 @@ * \date: 2020-06-04 * * \brief: Key Pairs class for ed25519 keys, used for default gradido transactions + * TODO: add verify method */ @@ -75,6 +76,9 @@ private: //! \brief ed25519 libsodium private key //! //! Why it is a pointer and the public is an array? + //! Because MemoryBin should be replaced by a memory obfuscation class which make it harder to steal the private key from computer memory + //! And because private key can be nullptr for example to verify a signed message + //! TODO: replace MemoryBin by a memory obfuscation class which make it hard to steal the private key from memory MemoryBin* mSodiumSecret; From f8c7d76530cb7cd778c48c850fe661e200b62125 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:36:02 +0200 Subject: [PATCH 012/195] extend memory bin to get access of part of data, for example copy the last half of it --- src/cpp/SingletonManager/MemoryManager.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpp/SingletonManager/MemoryManager.h b/src/cpp/SingletonManager/MemoryManager.h index 7cb9233f7..591148083 100644 --- a/src/cpp/SingletonManager/MemoryManager.h +++ b/src/cpp/SingletonManager/MemoryManager.h @@ -18,6 +18,7 @@ #include #include +#include #define MEMORY_MANAGER_PAGE_SIZE 10 @@ -41,6 +42,8 @@ public: inline unsigned char* data() { return mData; } inline const unsigned char* data() const { return mData; } + inline unsigned char* data(size_t startIndex) { assert(startIndex < mSize); return &mData[startIndex]; } + inline const unsigned char* data(size_t startIndex) const { assert(startIndex < mSize); return &mData[startIndex]; } std::string convertToHex(); //! \return 0 if ok //! -1 if bin is to small From fc11929fc1be96018f50d38fa18ed71a4c874b2d Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:37:13 +0200 Subject: [PATCH 013/195] Add hedera account page files and classes needed for this --- .../HTTPInterface/AdminHederaAccountPage.cpp | 125 ++++++++++++++++++ .../HTTPInterface/AdminHederaAccountPage.h | 20 +++ .../PageRequestHandlerFactory.cpp | 12 ++ src/cpp/controller/HederaAccount.cpp | 69 ++++++++++ src/cpp/controller/HederaAccount.h | 33 +++++ src/cpp/model/table/CryptoKey.h | 4 +- src/cpp/model/table/HederaAccount.cpp | 14 ++ src/cpp/model/table/HederaAccount.h | 4 +- src/cpsp/adminTopic.cpsp | 23 ++++ src/cpsp/header_large.cpsp | 19 +++ 10 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminHederaAccountPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminHederaAccountPage.h create mode 100644 src/cpp/controller/HederaAccount.cpp create mode 100644 src/cpp/controller/HederaAccount.h create mode 100644 src/cpsp/adminTopic.cpsp create mode 100644 src/cpsp/header_large.cpsp diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp new file mode 100644 index 000000000..0500a8996 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -0,0 +1,125 @@ +#include "AdminHederaAccountPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + + #include "../controller/HederaAccount.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +AdminHederaAccountPage::AdminHederaAccountPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + + const char* pageName = "Hedera Account"; + + // add + if(!form.empty()) { + + } + + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t\t
"; + // end include header_large.cpsp + responseStream << "\n"; +#line 21 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t
\n"; + responseStream << "\t

Einen neuen Account anlegen

\n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t
\n"; + responseStream << "
\n"; + // begin include footer.cpsp + responseStream << "
\n"; + responseStream << "

Copyright © Gradido 2020

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "

Login Server in Entwicklung

\n"; + responseStream << "

Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.h b/src/cpp/HTTPInterface/AdminHederaAccountPage.h new file mode 100644 index 000000000..b35f6ffb3 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.h @@ -0,0 +1,20 @@ +#ifndef AdminHederaAccountPage_INCLUDED +#define AdminHederaAccountPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminHederaAccountPage: public SessionHTTPRequestHandler +{ +public: + AdminHederaAccountPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminHederaAccountPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 50dc610af..11cdb7d78 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -28,6 +28,8 @@ #include "AdminUserPasswordReset.h" #include "RegisterDirectPage.h" #include "AdminGroupsPage.h" +#include "AdminTopicPage.h" +#include "AdminHederaAccountPage.h" #include "DecodeTransactionPage.h" #include "RepairDefectPassphrase.h" @@ -212,6 +214,16 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/topic") { + auto pageRequestHandler = new AdminTopicPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } + if (url_first_part == "/hedera_account") { + auto pageRequestHandler = new AdminHederaAccountPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp new file mode 100644 index 000000000..9a858bd7c --- /dev/null +++ b/src/cpp/controller/HederaAccount.cpp @@ -0,0 +1,69 @@ + +#include "HederaAccount.h" + +namespace controller { + + HederaAccount::HederaAccount(model::table::HederaAccount* dbModel) + { + mDBModel = dbModel; + } + + HederaAccount::~HederaAccount() + { + + } + + Poco::AutoPtr HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) + { + auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance); + auto group = new HederaAccount(db); + return Poco::AutoPtr(group); + } + + std::vector> HederaAccount::load(const std::string& alias) + { + auto db = new model::table::HederaAccount(); + auto group_list = db->loadFromDB("alias", alias, 0); + + std::vector> resultVector; + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + resultVector.push_back(new HederaAccount(new model::table::HederaAccount(*it))); + } + return resultVector; + } + + std::vector> HederaAccount::listAll() + { + auto db = new model::table::HederaAccount(); + std::vector group_list; + // throw an unresolved external symbol error + //group_list = db->loadAllFromDB(); + + // work around for not working call to loadAllFromDB + auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + + select << "SELECT id, alias, name, url, description FROM " << db->getTableName() + , Poco::Data::Keywords::into(group_list); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + } + catch (Poco::Exception& ex) { + printf("[Group::listAll] poco exception: %s\n", ex.displayText().data()); + } + // work around end + std::vector> resultVector; + + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + Poco::AutoPtr group_ptr(new HederaAccount(new model::table::HederaAccount(*it))); + resultVector.push_back(group_ptr); + } + return resultVector; + } + +} + diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h new file mode 100644 index 000000000..9efd89c12 --- /dev/null +++ b/src/cpp/controller/HederaAccount.h @@ -0,0 +1,33 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE + +#include "../model/table/HederaAccount.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + class HederaAccount : public TableControllerBase + { + public: + + ~HederaAccount(); + + static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + + static std::vector> load(const std::string& alias); + static std::vector> listAll(); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + HederaAccount(model::table::HederaAccount* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index 1a04dd387..f4fd8bebf 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -8,8 +8,8 @@ namespace model { namespace table { enum KeyType { - KEY_TYPE_SODIUM_ED25519, - KEY_TYPE_ED25519_REF10, + KEY_TYPE_SODIUM_ED25519 = 0, + KEY_TYPE_ED25519_REF10 = 1, KEY_TYPE_COUNT }; diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 4018c653a..63c6068bc 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -6,6 +6,20 @@ namespace model { namespace table { HederaAccount::HederaAccount() + : mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0) + { + + } + + HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) + : mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance) + { + + } + + HederaAccount::HederaAccount(const HederaAccountTuple& tuple) + : ModelBase(tuple.get<0>()), + mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()), mBalance(tuple.get<4>()), mUpdated(tuple.get<5>()) { } diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index c9c85b554..ca56dfd62 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -7,12 +7,14 @@ namespace model { namespace table { - typedef Poco::Tuple HederaAccountsTuple; + typedef Poco::Tuple HederaAccountTuple; class HederaAccount : public ModelBase { public: HederaAccount(); + HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + HederaAccount(const HederaAccountTuple& tuple); ~HederaAccount(); // generic db operations diff --git a/src/cpsp/adminTopic.cpsp b/src/cpsp/adminTopic.cpsp new file mode 100644 index 000000000..3eac5a976 --- /dev/null +++ b/src/cpsp/adminTopic.cpsp @@ -0,0 +1,23 @@ +<%@ page class="AdminTopicPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + +%> +<%% + const char* pageName = "Topic"; + + + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
+

Topic Admin Page

+
+
+ +
+<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/header_large.cpsp b/src/cpsp/header_large.cpsp new file mode 100644 index 000000000..2aa8f5f4b --- /dev/null +++ b/src/cpsp/header_large.cpsp @@ -0,0 +1,19 @@ +<%! +#include "../ServerConfig.h" +%><%% + bool withMaterialIcons = false; +%> + + + + + +Gradido Login Server: <%= pageName %> + +<% if(withMaterialIcons) { %> + +<% } %> + + +
+
\ No newline at end of file From e3cea5968b3e56376b896ffda64aa4f6361d2c88 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 13:14:33 +0200 Subject: [PATCH 014/195] add controller classes for new db tables crypto_keys and hedera_ids, update model tables for them --- src/cpp/Crypto/KeyPairHedera.cpp | 23 +++++++++++ src/cpp/Crypto/KeyPairHedera.h | 5 ++- src/cpp/SingletonManager/SessionManager.cpp | 1 + src/cpp/controller/CryptoKey.cpp | 44 +++++++++++++++++++++ src/cpp/controller/CryptoKey.h | 35 ++++++++++++++++ src/cpp/controller/HederaId.cpp | 32 +++++++++++++++ src/cpp/controller/HederaId.h | 32 +++++++++++++++ src/cpp/model/table/CryptoKey.cpp | 16 ++++++++ src/cpp/model/table/CryptoKey.h | 5 ++- src/cpp/model/table/HederaId.cpp | 7 ++++ src/cpp/model/table/HederaId.h | 1 + 11 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 src/cpp/controller/CryptoKey.cpp create mode 100644 src/cpp/controller/CryptoKey.h create mode 100644 src/cpp/controller/HederaId.cpp create mode 100644 src/cpp/controller/HederaId.h diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 80c4649b1..a0e0c5d43 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -145,4 +145,27 @@ bool KeyPairHedera::verify(const unsigned char* message, size_t messageSize, Mem return false; } return true; +} + +MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr password) const +{ + if (password.isNull()) return nullptr; + if (!mPrivateKey) return nullptr; + + MemoryBin* encryptedKey = nullptr; + if (SecretKeyCryptography::AUTH_ENCRYPT_OK == password->encrypt(mPrivateKey, &encryptedKey)) { + return encryptedKey; + } + else { + return nullptr; + } + +} + +MemoryBin* KeyPairHedera::getPublicKeyCopy() const +{ + auto mm = MemoryManager::getInstance(); + auto public_key = mm->getFreeMemory(ed25519_pubkey_SIZE); + memcpy(*public_key, mPublicKey, ed25519_pubkey_SIZE); + return public_key; } \ No newline at end of file diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 358a3b680..871453afc 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -13,6 +13,7 @@ #include "sodium.h" +#include "SecretKeyCryptography.h" #include "iroha-ed25519/include/ed25519/ed25519.h" class KeyPairHedera : public IKeyPair @@ -34,6 +35,7 @@ public: bool verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const; inline const unsigned char* getPublicKey() const { return mPublicKey; } + MemoryBin* getPublicKeyCopy() const; inline bool isTheSame(const KeyPairHedera& b) const { return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); @@ -60,7 +62,8 @@ public: inline bool hasPrivateKey() const { return mPrivateKey != nullptr; } - + //! \brief only way to get a private key.. encrypted + MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; protected: diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 3c2144b1a..8de83d6c5 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -329,6 +329,7 @@ Session* SessionManager::getSession(int handle) //mWorkingMutex.lock(); auto it = mRequestSessionMap.find(handle); if (it != mRequestSessionMap.end()) { + printf("[SessionManager::getSession] found existing session, try if active...\n"); result = it->second; if (!result->isActive()) { //printf("[SessionManager::getSession] session isn't active\n"); diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp new file mode 100644 index 000000000..809673bc5 --- /dev/null +++ b/src/cpp/controller/CryptoKey.cpp @@ -0,0 +1,44 @@ + +#include "CryptoKey.h" + +namespace controller { + + CryptoKey::CryptoKey(model::table::CryptoKey* dbModel) + { + mDBModel = dbModel; + } + + CryptoKey::~CryptoKey() + { + + } + + Poco::AutoPtr CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user) + { + auto mm = MemoryManager::getInstance(); + + auto encrypted_priv_key = hederaKeyPair->getCryptedPrivKey(user->getPassword()); + auto public_key = hederaKeyPair->getPublicKeyCopy(); + + auto db = new model::table::CryptoKey(encrypted_priv_key, public_key, model::table::KEY_TYPE_ED25519_HEDERA); + + mm->releaseMemory(encrypted_priv_key); + mm->releaseMemory(public_key); + + auto cryptoKey = new CryptoKey(db); + return Poco::AutoPtr(cryptoKey); + } + + Poco::AutoPtr CryptoKey::load(int id) + { + auto db = new model::table::CryptoKey(); + if (1 == db->loadFromDB("id", id)) { + auto cryptoKey = new CryptoKey(db); + return Poco::AutoPtr(cryptoKey); + } + return nullptr; + } + + +} + diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h new file mode 100644 index 000000000..9e76123ef --- /dev/null +++ b/src/cpp/controller/CryptoKey.h @@ -0,0 +1,35 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE + +#include "../model/table/CryptoKey.h" +#include "../Crypto/KeyPairHedera.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" +#include "User.h" + +namespace controller { + class CryptoKey : public TableControllerBase + { + public: + + ~CryptoKey(); + + static Poco::AutoPtr create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user); + + //! if returned ptr is NULL, dataset not found + static Poco::AutoPtr load(int id); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + CryptoKey(model::table::CryptoKey* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE \ No newline at end of file diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp new file mode 100644 index 000000000..e6d281907 --- /dev/null +++ b/src/cpp/controller/HederaId.cpp @@ -0,0 +1,32 @@ +#include "HederaId.h" + +namespace controller { + + HederaId::HederaId(model::table::HederaId* dbModel) + { + mDBModel = dbModel; + } + + HederaId::~HederaId() + { + + } + + Poco::AutoPtr HederaId::create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num) + { + auto db = new model::table::HederaId(shardNum, realmNum, num); + + auto hedera_id = new HederaId(db); + return Poco::AutoPtr(hedera_id); + } + + Poco::AutoPtr HederaId::load(int id) + { + auto db = new model::table::HederaId(); + if (1 == db->loadFromDB("id", id)) { + auto cryptoKey = new HederaId(db); + return Poco::AutoPtr(cryptoKey); + } + return nullptr; + } +} \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h new file mode 100644 index 000000000..f02e69373 --- /dev/null +++ b/src/cpp/controller/HederaId.h @@ -0,0 +1,32 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE + +#include "../model/table/HederaId.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + class HederaId : public TableControllerBase + { + public: + + ~HederaId(); + + static Poco::AutoPtr create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); + + static Poco::AutoPtr load(int id); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + HederaId(model::table::HederaId* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index 201047a5b..d36f44de6 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -9,6 +9,22 @@ namespace model { } + CryptoKey::CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType) + : mKeyType(keyType) + { + if (!privateKey) { + mPrivateKey = Poco::Nullable(); + } else { + mPrivateKey = Poco::Nullable(Poco::Data::BLOB(*privateKey, privateKey->size())); + } + + if (!publicKey) { + mPublicKey = Poco::Nullable(); + } else { + mPublicKey = Poco::Nullable(Poco::Data::BLOB(*publicKey, publicKey->size())); + } + } + CryptoKey::~CryptoKey() { diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index f4fd8bebf..58d6df5dc 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -8,8 +8,8 @@ namespace model { namespace table { enum KeyType { - KEY_TYPE_SODIUM_ED25519 = 0, - KEY_TYPE_ED25519_REF10 = 1, + KEY_TYPE_ED25519_SODIUM = 0, + KEY_TYPE_ED25519_HEDERA = 1, KEY_TYPE_COUNT }; @@ -17,6 +17,7 @@ namespace model { { public: CryptoKey(); + CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType); ~CryptoKey(); // generic db operations diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index b048a0d71..a4f25cc78 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -5,6 +5,13 @@ using namespace Poco::Data::Keywords; namespace model { namespace table { HederaId::HederaId() + : mShardNum(0), mRealmNum(0), mNum(0) + { + + } + + HederaId::HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num) + : mShardNum(shardNum), mRealmNum(realmNum), mNum(num) { } diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index ef35b2e70..c36d1f656 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -11,6 +11,7 @@ namespace model { { public: HederaId(); + HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); ~HederaId(); // generic db operations From 48b46e6345ab7dcb212f494811446cb1dc6bba4a Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 18:06:29 +0200 Subject: [PATCH 015/195] save entry of hedera account in db --- skeema/gradido_login/hedera_accounts.sql | 1 + .../HTTPInterface/AdminHederaAccountPage.cpp | 127 ++++++++++++++++-- src/cpp/SingletonManager/SessionManager.cpp | 2 + src/cpp/SingletonManager/SessionManager.h | 2 + src/cpp/controller/HederaAccount.cpp | 4 +- src/cpp/controller/HederaAccount.h | 2 +- src/cpp/model/table/CryptoKey.cpp | 4 +- src/cpp/model/table/HederaAccount.cpp | 29 ++-- src/cpp/model/table/HederaAccount.h | 12 +- 9 files changed, 159 insertions(+), 24 deletions(-) diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql index 23ffa33d1..c8fcff4eb 100644 --- a/skeema/gradido_login/hedera_accounts.sql +++ b/skeema/gradido_login/hedera_accounts.sql @@ -4,6 +4,7 @@ CREATE TABLE `hedera_accounts` ( `account_hedera_id` int unsigned NOT NULL, `account_key_id` int unsigned NOT NULL, `balance` bigint unsigned NOT NULL DEFAULT '0', + `network_type` int NOT NULL DEFAULT '0', `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `account_hedera_id` (`account_hedera_id`), diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 0500a8996..884bc1cdc 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -7,7 +7,13 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - #include "../controller/HederaAccount.h" + +#include "../controller/HederaAccount.h" +#include "../controller/HederaId.h" +#include "../controller/CryptoKey.h" +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" + #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" #include "../ServerConfig.h" @@ -27,15 +33,104 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + auto user = mSession->getNewUser(); // add if(!form.empty()) { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* privateKey = nullptr; + MemoryBin* publicKey = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + if(!hedera_id->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving hedera id in DB")); + } + + privateKey = DataTypeConverter::hexToBin(privateKeyString); + publicKey = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(privateKey, publicKey); + mm->releaseMemory(privateKey); + mm->releaseMemory(publicKey); + auto crypto_key = controller::CryptoKey::create(&key_pair, user); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + + if(0 == errorCount()) { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + } } - #line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" @@ -74,7 +169,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 21 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 116 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; @@ -84,15 +179,31 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
\n"; diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 8de83d6c5..8d0b77928 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -47,6 +47,8 @@ bool SessionManager::init() case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-_])[A-Za-z0-9@$!%*?&+-_]{8,}$"); break; case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; + case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; + case VALIDATE_ONLY_HEX: mValidations[i] = new Poco::RegularExpression("^(0x)?[a-fA-F0-9]*$"); break; case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break; case VALIDATE_HAS_UPPERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index 208de09be..d57162305 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -28,6 +28,8 @@ enum SessionValidationTypes { VALIDATE_PASSWORD, VALIDATE_PASSPHRASE, VALIDATE_HAS_NUMBER, + VALIDATE_ONLY_INTEGER, + VALIDATE_ONLY_HEX, VALIDATE_HAS_SPECIAL_CHARACTER, VALIDATE_HAS_UPPERCASE_LETTER, VALIDATE_HAS_LOWERCASE_LETTER, diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 9a858bd7c..42a08eb27 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -13,9 +13,9 @@ namespace controller { } - Poco::AutoPtr HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) + Poco::AutoPtr HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, model::table::HederaNetworkType type/* = HEDERA_MAINNET*/) { - auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance); + auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance, type); auto group = new HederaAccount(db); return Poco::AutoPtr(group); } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 9efd89c12..fd2cb4b23 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -14,7 +14,7 @@ namespace controller { ~HederaAccount(); - static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); static std::vector> load(const std::string& alias); static std::vector> listAll(); diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index d36f44de6..9588f57e7 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -43,8 +43,8 @@ namespace model { const char* CryptoKey::typeToString(KeyType type) { switch (type) { - case KEY_TYPE_ED25519_REF10: return "ed25519 ref10"; - case KEY_TYPE_SODIUM_ED25519: return "sodium ed22519"; + case KEY_TYPE_ED25519_SODIUM: return "ed25519 ref10"; + case KEY_TYPE_ED25519_HEDERA: return "sodium ed22519"; } return ""; } diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 63c6068bc..06538fdcb 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -6,20 +6,21 @@ namespace model { namespace table { HederaAccount::HederaAccount() - : mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0) + : mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0), mType(0) { } - HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) - : mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance) + HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, HederaNetworkType type /*= HEDERA_MAINNET*/) + : mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance), mType(type) { } HederaAccount::HederaAccount(const HederaAccountTuple& tuple) : ModelBase(tuple.get<0>()), - mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()), mBalance(tuple.get<4>()), mUpdated(tuple.get<5>()) + mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()), + mBalance(tuple.get<4>()), mType(tuple.get<5>()), mUpdated(tuple.get<6>()) { } @@ -37,18 +38,28 @@ namespace model { ss << "account crypto key id: " << std::to_string(mAccountKeyId) << std::endl; // balance in tinybars, 100,000,000 tinybar = 1 HashBar ss << "account balance: " << std::to_string((double)(mBalance) * 100000000.0) << " HBAR" << std::endl; + ss << "Hedera Net Type: " << hederaNetworkTypeToString((HederaNetworkType)mType) << std::endl; ss << "last update: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl; return ss.str(); } + const char* HederaAccount::hederaNetworkTypeToString(HederaNetworkType type) + { + switch (type) { + case HEDERA_MAINNET: return "Mainnet"; + case HEDERA_TESTNET: return "Testnet"; + default: return ""; + } + } + Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); - select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, network_type, updated FROM " << getTableName() << " where " << fieldName << " = ?" - , into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mUpdated); + , into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mType), into(mUpdated); return select; @@ -57,7 +68,7 @@ namespace model { Poco::Data::Statement HederaAccount::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); - select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, network_type, updated FROM " << getTableName() << " where " << fieldName << " LIKE ?"; return select; @@ -77,8 +88,8 @@ namespace model { Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (user_id, account_hedera_id, account_key_id, balance) VALUES(?,?,?,?)" - , use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance); + << " (user_id, account_hedera_id, account_key_id, balance, network_type) VALUES(?,?,?,?,?)" + , use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance), use(mType); unlock(); return insert; } diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index ca56dfd62..2219fc521 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -7,13 +7,19 @@ namespace model { namespace table { - typedef Poco::Tuple HederaAccountTuple; + typedef Poco::Tuple HederaAccountTuple; + + enum HederaNetworkType { + HEDERA_MAINNET, + HEDERA_TESTNET, + HEDERA_NET_COUNT + }; class HederaAccount : public ModelBase { public: HederaAccount(); - HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, HederaNetworkType type = HEDERA_MAINNET); HederaAccount(const HederaAccountTuple& tuple); ~HederaAccount(); @@ -21,6 +27,7 @@ namespace model { const char* getTableName() const { return "hedera_accounts"; } std::string toString(); + static const char* hederaNetworkTypeToString(HederaNetworkType type); protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); @@ -32,6 +39,7 @@ namespace model { int mAccountHederaId; int mAccountKeyId; Poco::UInt64 mBalance; + int mType; Poco::DateTime mUpdated; }; From 41d8649d7af36a96a1ac39985a62127908c1ea00 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 31 Aug 2020 11:23:58 +0200 Subject: [PATCH 016/195] show and add node server and hedera accounts, model, controller and page --- skeema/gradido_login/crypto_keys.sql | 3 +- skeema/gradido_login/hedera_accounts.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 12 +- src/cpp/Crypto/KeyPairHedera.h | 1 + src/cpp/HTTPInterface/AdminGroupsPage.cpp | 83 ++-- .../HTTPInterface/AdminHederaAccountPage.cpp | 112 ++++-- src/cpp/HTTPInterface/AdminNodeServerPage.cpp | 363 ++++++++++++++++++ src/cpp/HTTPInterface/AdminNodeServerPage.h | 20 + .../PageRequestHandlerFactory.cpp | 6 + .../SingletonManager/ConnectionManager.cpp | 6 +- src/cpp/SingletonManager/SessionManager.cpp | 2 + src/cpp/SingletonManager/SessionManager.h | 1 + src/cpp/controller/CryptoKey.cpp | 23 ++ src/cpp/controller/CryptoKey.h | 2 + src/cpp/controller/Group.cpp | 2 +- src/cpp/controller/HederaAccount.cpp | 14 +- src/cpp/controller/HederaAccount.h | 7 +- src/cpp/controller/NodeServer.cpp | 145 +++++++ src/cpp/controller/NodeServer.h | 52 +++ src/cpp/model/table/HederaAccount.h | 9 + src/cpp/model/table/HederaId.cpp | 31 +- src/cpp/model/table/HederaId.h | 3 + src/cpp/model/table/ModelBase.cpp | 14 +- src/cpp/model/table/NodeServer.cpp | 114 ++++++ src/cpp/model/table/NodeServer.h | 71 ++++ src/cpsp/adminGroups.cpsp | 22 +- src/cpsp/adminNodeServer.cpsp | 200 ++++++++++ src/cpsp/header_large.cpsp | 10 + 28 files changed, 1232 insertions(+), 98 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminNodeServerPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminNodeServerPage.h create mode 100644 src/cpp/controller/NodeServer.cpp create mode 100644 src/cpp/controller/NodeServer.h create mode 100644 src/cpp/model/table/NodeServer.cpp create mode 100644 src/cpp/model/table/NodeServer.h create mode 100644 src/cpsp/adminNodeServer.cpsp diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index 43b511db2..c90750ae3 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -3,5 +3,6 @@ CREATE TABLE `crypto_keys` ( `private_key` varbinary(64) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE(`public_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql index c8fcff4eb..8ce24b54d 100644 --- a/skeema/gradido_login/hedera_accounts.sql +++ b/skeema/gradido_login/hedera_accounts.sql @@ -5,7 +5,7 @@ CREATE TABLE `hedera_accounts` ( `account_key_id` int unsigned NOT NULL, `balance` bigint unsigned NOT NULL DEFAULT '0', `network_type` int NOT NULL DEFAULT '0', - `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `account_hedera_id` (`account_hedera_id`), UNIQUE KEY `account_key_id` (`account_key_id`) diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index a0e0c5d43..0a3bf4bc2 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -46,9 +46,10 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi default: throw std::exception("[KeyPairHedera] invalid private key"); } - crypto_sign_ed25519_sk_to_pk(mPublicKey, *mPrivateKey); + + // check public } - else if (publicKey) { + if (publicKey) { switch (publicKey->size()) { case 32: { // raw public key @@ -64,8 +65,13 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi throw std::exception("[KeyPairHedera] invalid public key"); } } + auto public_key_2 = mm->getFreeMemory(ed25519_pubkey_SIZE); + crypto_sign_ed25519_sk_to_pk(*public_key_2, *mPrivateKey); + if (sodium_memcmp(*public_key_2, mPublicKey, ed25519_pubkey_SIZE) != 0) { + throw "public keys not match"; + } - + mm->releaseMemory(public_key_2); mm->releaseMemory(derPrefixPriv); mm->releaseMemory(derPrefixPub); } diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 871453afc..115beebdb 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -70,6 +70,7 @@ protected: KeyPairHedera(); void createKeyFromSeed(const MemoryBin* seed); + private: // 64 Byte //! \brief ed25519 libsodium private key diff --git a/src/cpp/HTTPInterface/AdminGroupsPage.cpp b/src/cpp/HTTPInterface/AdminGroupsPage.cpp index 1e6619801..7e38cfde2 100644 --- a/src/cpp/HTTPInterface/AdminGroupsPage.cpp +++ b/src/cpp/HTTPInterface/AdminGroupsPage.cpp @@ -8,7 +8,7 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" #include "../controller/Group.h" -#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" #include "../ServerConfig.h" @@ -55,14 +55,14 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: //auto groups = controller::Group::load("gdd1"); //std::vector> groups; -#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" bool withMaterialIcons = false; std::ostream& _responseStream = response.send(); Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; responseStream << "\n"; - // begin include header.cpsp + // begin include header_large.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; @@ -70,47 +70,48 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: responseStream << "\n"; responseStream << "\n"; responseStream << "Gradido Login Server: "; -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" responseStream << ( pageName ); responseStream << "\n"; responseStream << "\n"; -#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" if(withMaterialIcons) { responseStream << "\n"; responseStream << "\n"; -#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" } responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "
\n"; - responseStream << "
\n"; - responseStream << " "; - // end include header.cpsp + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t
"; + // end include header_large.cpsp responseStream << "\n"; #line 38 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( getErrorsHtml() ); @@ -122,11 +123,11 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: responseStream << "\t\t
\t\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t
ID
\n"; - responseStream << "\t\t\t\t
Name
\n"; - responseStream << "\t\t\t\t
Alias
\n"; - responseStream << "\t\t\t\t
Url
\n"; - responseStream << "\t\t\t\t
"; + responseStream << "\t\t\t\t
ID
\n"; + responseStream << "\t\t\t\t
Name
\n"; + responseStream << "\t\t\t\t
Alias
\n"; + responseStream << "\t\t\t\t
Url
\n"; + responseStream << "\t\t\t\t
"; #line 50 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( gettext("Description") ); responseStream << "
\n"; @@ -136,23 +137,23 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: for(auto it = groups.begin(); it != groups.end(); it++) { auto group_model = (*it)->getModel(); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t\t\t
"; + responseStream << "\t\t\t\t\t
"; #line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getID() ); responseStream << "
\n"; - responseStream << "\t\t\t\t\t
"; + responseStream << "\t\t\t\t\t
"; #line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getName() ); responseStream << "
\n"; - responseStream << "\t\t\t\t\t
"; + responseStream << "\t\t\t\t\t
"; #line 57 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getAlias() ); responseStream << "
\n"; - responseStream << "\t\t\t\t\t
"; + responseStream << "\t\t\t\t\t
"; #line 58 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getUrl() ); responseStream << "
\n"; - responseStream << "\t\t\t\t\t
"; + responseStream << "\t\t\t\t\t
"; #line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getDescription()); responseStream << "
\n"; diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 884bc1cdc..0de7a6922 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -55,8 +55,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request int num = 0; int networkType = 0; - MemoryBin* privateKey = nullptr; - MemoryBin* publicKey = nullptr; + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; // validate if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { @@ -100,22 +100,22 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(0 == errorCount()) { auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); - if(!hedera_id->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving hedera id in DB")); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); } - - privateKey = DataTypeConverter::hexToBin(privateKeyString); - publicKey = DataTypeConverter::hexToBin(publicKeyString); - - - KeyPairHedera key_pair(privateKey, publicKey); - mm->releaseMemory(privateKey); - mm->releaseMemory(publicKey); - auto crypto_key = controller::CryptoKey::create(&key_pair, user); - if(!crypto_key->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving crypto key in DB")); - } - if(0 == errorCount()) { auto hedera_account = controller::HederaAccount::create( user->getModel()->getID(), @@ -128,10 +128,15 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request addError(new Error("DB Error", "Error saving hedera account into DB")); } } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); } } + // list accounts + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); #line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" @@ -166,13 +171,74 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\n"; responseStream << "\n"; responseStream << "
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 116 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

Deine Hedera Accounts

\n"; + responseStream << "\t\t
\t\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t
Hedera Id
\t\t\t\n"; + responseStream << "\t\t\t\t
Balance
\n"; + responseStream << "\t\t\t\t
Server Type
\n"; + responseStream << "\t\t\t\t
Last Updated
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t"; +#line 134 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { + auto hedera_account_model = (*it)->getModel(); + responseStream << "\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t
"; +#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( (*it)->getHederaId()->getModel()->toString() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( hedera_account_model->getBalanceDouble() ); + responseStream << " hbar
\n"; + responseStream << "\t\t\t\t\t
"; +#line 140 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 141 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( hedera_account_model->getUpdatedString() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t"; +#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + } responseStream << "\n"; + responseStream << "\t\t
\n"; + responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t

Einen neuen Account anlegen

\n"; responseStream << "\t
\n"; @@ -189,21 +255,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\n"; diff --git a/src/cpp/HTTPInterface/AdminNodeServerPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerPage.cpp new file mode 100644 index 000000000..c6c786aeb --- /dev/null +++ b/src/cpp/HTTPInterface/AdminNodeServerPage.cpp @@ -0,0 +1,363 @@ +#include "AdminNodeServerPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + + +#include "../controller/NodeServer.h" +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" +#include "../lib/DataTypeConverter.h" + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +AdminNodeServerPage::AdminNodeServerPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminNodeServerPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + + const char* pageName = "Node Server"; + auto sm = SessionManager::getInstance(); + + // add + if(!form.empty()) { + // collect + auto url = form.get("node-server-url", ""); + auto portString = form.get("node-server-port", ""); + auto nodeServerTypeString = form.get("node-server-type", "0"); + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto nodeServerGroupString = form.get("node-server-group", ""); + + int port = 0; + int shardNum = 0; + int realmNum = 0; + int num = 0; + model::table::NodeServerType nodeServerType = model::table::NODE_SERVER_NONE; + int group_id = 0; + + + // validate + if(!sm->isValid(url, VALIDATE_ONLY_URL)) { + addError(new ParamError("Node Server", "Url not valid, must start with http or https", url)); + + } + if(!sm->isValid(portString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server", "Port isn't valid integer")); + } else { + if(DataTypeConverter::strToInt(portString, port) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting port to int")); + } + } + + if(!sm->isValid(nodeServerTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server Type", "not integer")); + } else { + int node_server_type_int = 0; + if(DataTypeConverter::strToInt(nodeServerTypeString, node_server_type_int) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting node server type to int")); + } + if(node_server_type_int < 0 || node_server_type_int >= (int)model::table::NODE_SERVER_TYPE_COUNT) { + addError(new Error("Node Server Type", "invalid value")); + } else { + nodeServerType = (model::table::NodeServerType)node_server_type_int; + } + } + if(model::table::NodeServerIsHederaNode(nodeServerType)) { + + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + } else if(model::table::NodeServerHasGroup(nodeServerType)) { + if(!sm->isValid(nodeServerGroupString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(nodeServerGroupString, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } + } + + + + if(0 == errorCount()) { + int hedera_id_int = 0; + if(NodeServerIsHederaNode(nodeServerType)) { + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + hedera_id_int = hedera_id->getModel()->getID(); + } + + auto node_server = controller::NodeServer::create( + url, port, group_id, (model::table::NodeServerType)nodeServerType, hedera_id_int + ); + if(!node_server->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving Node Server in DB")); + } + } + } + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } + + auto node_servers = controller::NodeServer::listAll(); + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t
"; + // end include header_large.cpsp + responseStream << "\n"; +#line 126 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

Alle Node Server

\n"; + responseStream << "\t\t
\t\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t
Server Type
\n"; + responseStream << "\t\t\t\t
Url:Port
\n"; + responseStream << "\t\t\t\t
Group / Hedera Id
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t"; +#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + for(auto it = node_servers.begin(); it != node_servers.end(); it++) { + auto node_server_model = (*it)->getModel(); + responseStream << "\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t
"; +#line 142 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( model::table::NodeServer::nodeServerTypeToString(node_server_model->getNodeServerType()) ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
"; +#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( node_server_model->getUrlWithPort() ); + responseStream << "
\n"; + responseStream << "\t\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t\t"; +#line 145 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + if(node_server_model->isHederaNode()) { + auto hedera_id_model = (*it)->getHederaId()->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t"; +#line 147 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( hedera_id_model->toString() ); + responseStream << "\n"; + responseStream << "\t\t\t\t\t\t"; +#line 148 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } else if(node_server_model->hasGroup()){ + auto groupIt = group_indices.find(node_server_model->getGroupId()); + if(groupIt != group_indices.end()) { + auto group_model = groups[groupIt->second]->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t\tgetDescription() ); + responseStream << "\">"; +#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( group_model->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t"; +#line 153 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } else { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t\t"; +#line 154 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( node_server_model->getGroupId() ); + responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t"; +#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\t"; +#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t"; +#line 159 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } responseStream << "\n"; + responseStream << "\t\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t

Ein Node Server hinzufügen

\n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\tNur für Hedera Nodes\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\tNur für Gradido Nodes\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t
\n"; + responseStream << "
\n"; + responseStream << "\n"; + // begin include footer.cpsp + responseStream << "
\n"; + responseStream << "

Copyright © Gradido 2020

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "

Login Server in Entwicklung

\n"; + responseStream << "

Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminNodeServerPage.h b/src/cpp/HTTPInterface/AdminNodeServerPage.h new file mode 100644 index 000000000..4a60b45e7 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminNodeServerPage.h @@ -0,0 +1,20 @@ +#ifndef AdminNodeServerPage_INCLUDED +#define AdminNodeServerPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminNodeServerPage: public SessionHTTPRequestHandler +{ +public: + AdminNodeServerPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminNodeServerPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 11cdb7d78..b31e742c0 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -30,6 +30,7 @@ #include "AdminGroupsPage.h" #include "AdminTopicPage.h" #include "AdminHederaAccountPage.h" +#include "AdminNodeServerPage.h" #include "DecodeTransactionPage.h" #include "RepairDefectPassphrase.h" @@ -224,6 +225,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/nodes") { + auto pageRequestHandler = new AdminNodeServerPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/SingletonManager/ConnectionManager.cpp b/src/cpp/SingletonManager/ConnectionManager.cpp index c8752ee6e..05a8802ee 100644 --- a/src/cpp/SingletonManager/ConnectionManager.cpp +++ b/src/cpp/SingletonManager/ConnectionManager.cpp @@ -56,7 +56,7 @@ bool ConnectionManager::setConnectionsFromConfig(const Poco::Util::LayeredConfig dbConfig << "db=" << dbName << ";"; dbConfig << "user=" << config.getString(firstKeyPart + ".db.user", "root") << ";"; dbConfig << "password=" << config.getString(firstKeyPart + ".db.password", "") << ";"; - dbConfig << "auto-reconnect=false"; + dbConfig << "auto-reconnect=true"; setConnection(dbConfig.str(), type); @@ -73,10 +73,10 @@ Poco::Data::Session ConnectionManager::getConnection(ConnectionType type) throw Poco::NotFoundException("Connection Type unknown", std::to_string(type)); } auto session = mSessionPools.getPool(mSessionPoolNames[type]).get(); - if (!session.isConnected()) { + /*if (!session.isConnected()) { printf("reconnect called\n"); session.reconnect(); - } + }*/ //std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); //printf("[getConnection] %s impl: %p\n", dateTimeString.data(), session.impl()); return session; diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 8d0b77928..f8dbb318f 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -49,6 +49,8 @@ bool SessionManager::init() case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; case VALIDATE_ONLY_HEX: mValidations[i] = new Poco::RegularExpression("^(0x)?[a-fA-F0-9]*$"); break; + //case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}$"); break; + case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\/?"); break; case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break; case VALIDATE_HAS_UPPERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index d57162305..5968e3a25 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -30,6 +30,7 @@ enum SessionValidationTypes { VALIDATE_HAS_NUMBER, VALIDATE_ONLY_INTEGER, VALIDATE_ONLY_HEX, + VALIDATE_ONLY_URL, VALIDATE_HAS_SPECIAL_CHARACTER, VALIDATE_HAS_UPPERCASE_LETTER, VALIDATE_HAS_LOWERCASE_LETTER, diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 809673bc5..2e7d343ec 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -1,5 +1,6 @@ #include "CryptoKey.h" +#include "../SingletonManager/ErrorManager.h" namespace controller { @@ -39,6 +40,28 @@ namespace controller { return nullptr; } + Poco::AutoPtr CryptoKey::load(MemoryBin* publicKey) + { + return load(*publicKey, publicKey->size()); + } + + Poco::AutoPtr CryptoKey::load(const unsigned char* publicKey, size_t size) + { + assert(publicKey); + assert(size); + + Poco::Data::BLOB public_key_blob(publicKey, size); + auto db = new model::table::CryptoKey(); + auto count = db->loadFromDB("public_key", public_key_blob); + if (!count) return nullptr; + if (1 == count) return new CryptoKey(db); + + auto em = ErrorManager::getInstance(); + em->addError(new Error("CryptoKey::load", "found more than one crypto key with same public key")); + em->sendErrorsAsEmail(); + return nullptr; + } + } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index 9e76123ef..6e4e110bb 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -20,6 +20,8 @@ namespace controller { //! if returned ptr is NULL, dataset not found static Poco::AutoPtr load(int id); + static Poco::AutoPtr load(MemoryBin* publicKey); + static Poco::AutoPtr load(const unsigned char* publicKey, size_t size); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } diff --git a/src/cpp/controller/Group.cpp b/src/cpp/controller/Group.cpp index d5b3eb2ba..2d809da07 100644 --- a/src/cpp/controller/Group.cpp +++ b/src/cpp/controller/Group.cpp @@ -23,7 +23,7 @@ namespace controller { std::vector> Group::load(const std::string& alias) { auto db = new model::table::Group(); - auto group_list = db->loadFromDB("alias", alias, 0); + auto group_list = db->loadFromDB("alias", alias, 1); std::vector> resultVector; resultVector.reserve(group_list.size()); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 42a08eb27..9f4ff5b40 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -20,15 +20,19 @@ namespace controller { return Poco::AutoPtr(group); } - std::vector> HederaAccount::load(const std::string& alias) + std::vector> HederaAccount::load(const std::string& fieldName, int fieldValue) { auto db = new model::table::HederaAccount(); - auto group_list = db->loadFromDB("alias", alias, 0); + auto hedera_account_list = db->loadFromDB(fieldName, fieldValue, 2); std::vector> resultVector; - resultVector.reserve(group_list.size()); - for (auto it = group_list.begin(); it != group_list.end(); it++) { - resultVector.push_back(new HederaAccount(new model::table::HederaAccount(*it))); + resultVector.reserve(hedera_account_list.size()); + for (auto it = hedera_account_list.begin(); it != hedera_account_list.end(); it++) { + //mHederaID + auto db = new model::table::HederaAccount(*it); + auto hedera_account = new HederaAccount(db); + hedera_account->mHederaID = HederaId::load(db->getAccountHederaId()); + resultVector.push_back(hedera_account); } return resultVector; } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index fd2cb4b23..dd4c97435 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -1,6 +1,7 @@ #ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE #define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE +#include "../controller/HederaId.h" #include "../model/table/HederaAccount.h" #include "Poco/SharedPtr.h" @@ -11,21 +12,23 @@ namespace controller { class HederaAccount : public TableControllerBase { public: - ~HederaAccount(); static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); - static std::vector> load(const std::string& alias); + static std::vector> load(const std::string& fieldName, int fieldValue); static std::vector> listAll(); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } + inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } + inline Poco::AutoPtr getHederaId() { return mHederaID; } protected: HederaAccount(model::table::HederaAccount* dbModel); + Poco::AutoPtr mHederaID; }; } diff --git a/src/cpp/controller/NodeServer.cpp b/src/cpp/controller/NodeServer.cpp new file mode 100644 index 000000000..6096b2839 --- /dev/null +++ b/src/cpp/controller/NodeServer.cpp @@ -0,0 +1,145 @@ +#include "NodeServer.h" +#include "../SingletonManager/ErrorManager.h" +#include "../SingletonManager/ConnectionManager.h" + +namespace controller { + + + NodeServer::NodeServer(model::table::NodeServer* dbModel) + { + mDBModel = dbModel; + } + + NodeServer::~NodeServer() + { + + } + + Poco::AutoPtr NodeServer::create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId) + { + auto db = new model::table::NodeServer(url, port, groupId, type, nodeHederaId); + auto group = new NodeServer(db); + return Poco::AutoPtr(group); + } + + std::vector> NodeServer::load(model::table::NodeServerType type, int group_id/* = 0*/) + { + auto db = new model::table::NodeServer(); + std::vector node_server_list; + + if (type == model::table::NODE_SERVER_HEDERA_MAINNET_NODE || type == model::table::NODE_SERVER_HEDERA_TESTNET_NODE) + { + node_server_list = db->loadFromDB("server_type", type, 4); + } + else if (type == model::table::NODE_SERVER_GRADIDO_NODE) + { + if (group_id) + { + node_server_list = db->loadFromDB( + { "server_type", "group_id" }, + { type, group_id }, + model::table::MYSQL_CONDITION_AND + ); + } + else + { + node_server_list = db->loadFromDB("server_type", type, 4); + } + } + //auto node_server_list = db->loadFromDB("alias", alias, 0); + + std::vector> resultVector; + resultVector.reserve(node_server_list.size()); + for (auto it = node_server_list.begin(); it != node_server_list.end(); it++) { + resultVector.push_back(new NodeServer(new model::table::NodeServer(*it))); + } + return resultVector; + } + + /* + SELECT * FROM table_name + ORDER BY RAND() + LIMIT 1; + */ + NodeServerConnection NodeServer::pick(model::table::NodeServerType type, int group_id/* = 0*/) + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + NodeServerConnection result; + int hedera_node_id = 0; + + Poco::Data::Statement select(session); + select << "SELECT url, port"; + + if (model::table::NodeServerIsHederaNode(type)) { + select << ", node_hedera_id"; + } + select << " from node_servers ORDER BY RAND() LIMIT 1" + , Poco::Data::Keywords::into(result.url) + , Poco::Data::Keywords::into(result.port); + if (model::table::NodeServerIsHederaNode(type)) { + select, Poco::Data::Keywords::into(hedera_node_id); + } + try { + if (1 == select.execute()) { + if (model::table::NodeServerIsHederaNode(type)) { + result.hederaId = controller::HederaId::load(hedera_node_id); + } + return result; + } + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + const char* functionName = "NodeServer::pick"; + em->addError(new ParamError(functionName, "mysql error by pick: ", ex.message())); + em->addError(new ParamError(functionName, "server type: ", model::table::NodeServer::nodeServerTypeToString(type))); + em->addError(new ParamError(functionName, "group id", group_id)); + em->sendErrorsAsEmail(); + } + return result; + + } + + std::vector> NodeServer::listAll() + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); + std::vector rows; + // typedef Poco::Tuple NodeServerFullTuple; + select << "SELECT n.id, n.url, n.port, n.group_id, n.server_type, n.node_hedera_id, h.shardNum, h.realmNum, h.num, n.last_live_sign " + << "FROM node_servers as n " + << "LEFT JOIN hedera_ids as h ON h.id = n.node_hedera_id" + , Poco::Data::Keywords::into(rows); + + try { + select.executeAsync(); + select.wait(); + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + const char* functionName = "NodeServer::listAll"; + em->addError(new ParamError(functionName, "mysql error by list all: ", ex.message())); + em->sendErrorsAsEmail(); + } + std::vector> results; + for (auto it = rows.begin(); it != rows.end(); it++) { + //NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId); + auto row = *it; + model::table::NodeServer* db = new model::table::NodeServer( + row.get<1>(), row.get<2>(), row.get<3>(), (model::table::NodeServerType)row.get<4>(), row.get<5>() + ); + db->setLastLiveSign(row.get<9>()); + db->setID(row.get<0>()); + Poco::AutoPtr node_server(new NodeServer(db)); + node_server->setHederaId(controller::HederaId::create( + row.get<6>(), row.get<7>(), row.get<8>() + )); + results.push_back(node_server); + + } + return results; + + } + +} \ No newline at end of file diff --git a/src/cpp/controller/NodeServer.h b/src/cpp/controller/NodeServer.h new file mode 100644 index 000000000..5a2750194 --- /dev/null +++ b/src/cpp/controller/NodeServer.h @@ -0,0 +1,52 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE + +#include "../model/table/NodeServer.h" +#include "../controller/HederaId.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + + struct NodeServerConnection + { + NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {} + NodeServerConnection() :port(0) {}; + + bool isValid() { return url != "" && port; } + std::string url; + int port; + + Poco::AutoPtr hederaId; + }; + + typedef Poco::Tuple NodeServerFullTuple; + + class NodeServer : public TableControllerBase + { + public: + + ~NodeServer(); + + static Poco::AutoPtr create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId); + + static std::vector> load(model::table::NodeServerType type, int group_id = 0); + static std::vector> listAll(); + // pick server randomly + NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0); + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } + inline Poco::AutoPtr getHederaId() { return mHederaID; } + protected: + NodeServer(model::table::NodeServer* dbModel); + Poco::AutoPtr mHederaID; + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 2219fc521..c38af1df1 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -29,6 +29,15 @@ namespace model { static const char* hederaNetworkTypeToString(HederaNetworkType type); + inline int getAccountHederaId() { return mAccountHederaId; } + + inline Poco::UInt64 getBalance() { return mBalance; } + inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } + + inline HederaNetworkType getNetworkType() { return (HederaNetworkType)mType; } + + inline std::string getUpdatedString() { return Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S"); } + protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index a4f25cc78..9f26f05c5 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -24,12 +24,37 @@ namespace model { std::string HederaId::toString() { std::stringstream ss; - ss << "Shard Num: " << std::to_string(mShardNum) << std::endl; - ss << "Realm Num: " << std::to_string(mRealmNum) << std::endl; - ss << "Num: " << std::to_string(mNum) << std::endl; + ss << std::to_string(mShardNum) << "." << std::to_string(mRealmNum) << "." << std::to_string(mNum) << std::endl; return ss.str(); } + int HederaId::getID() + { + auto cm = ConnectionManager::getInstance(); + Poco::ScopedLock _lock(mWorkMutex); + + assert(mNum != 0|| mShardNum != 0 || mRealmNum != 0); + if (mID) return mID; + + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); + select << "SELECT id FROM " << getTableName() + << " where shardNum = ? AND realmNum = ? AND num = ?" + , into(mID), use(mShardNum), use(mRealmNum), use(mNum); + + try { + if (1 == select.execute()) { + return mID; + } + } + catch (Poco::Exception& ex) { + addError(new ParamError("HederaId::getID", "mysql error try to find existing entry", ex.message())); + sendErrorsAsEmail(); + } + insertIntoDB(true); + return mID; + } + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index c36d1f656..8de69c2a9 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -18,6 +18,9 @@ namespace model { const char* getTableName() const { return "hedera_ids"; } std::string toString(); + //! \brief check if hedera id already in db, then return id, else insert in db and return + int getID(); + protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index 4b55ea084..7bb7301f6 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -43,21 +43,27 @@ namespace model { //printf("ModelBase::insertIntoDB with table: %s\n", getTableName()); auto cm = ConnectionManager::getInstance(); Poco::ScopedLock _lock(mWorkMutex); - Poco::Data::Statement insert = _insertIntoDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement insert = _insertIntoDB(session); size_t resultCount = 0; try { - if (insert.execute() == 1) { + if (insert.execute(true) == 1) { // load id from db if (loadId) { - Poco::Data::Statement select = _loadIdFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + Poco::Data::Statement select = _loadIdFromDB(session); try { - return select.execute() == 1; + select.executeAsync(); + return select.wait() == 1; } catch (Poco::Exception& ex) { addError(new ParamError(getTableName(), "mysql error by select id", ex.displayText().data())); addError(new ParamError(getTableName(), "data set: ", toString().data())); } + select.reset(session); + select = _loadIdFromDB(session); + //Poco::Data::Statement select = _loadIdFromDB(session); + select.execute(); } else { return true; diff --git a/src/cpp/model/table/NodeServer.cpp b/src/cpp/model/table/NodeServer.cpp new file mode 100644 index 000000000..ae3bdbf81 --- /dev/null +++ b/src/cpp/model/table/NodeServer.cpp @@ -0,0 +1,114 @@ + +#include "NodeServer.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + + bool NodeServerIsHederaNode(NodeServerType type) { + return type == NODE_SERVER_HEDERA_MAINNET_NODE || type == NODE_SERVER_HEDERA_TESTNET_NODE; + } + bool NodeServerHasGroup(NodeServerType type) { + return type == NODE_SERVER_GRADIDO_NODE || type == NODE_SERVER_GRADIDO_COMMUNITY; + } + + + NodeServer::NodeServer() + : mPort(0), mGroupId(0), mServerType(0), mNodeHederaId(0) + { + + } + + NodeServer::NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId) + : mUrl(url), mPort(port), mGroupId(groupId), mServerType(type), mNodeHederaId(nodeHederaId) + { + } + + + + NodeServer::NodeServer(const NodeServerTuple& tuple) + : ModelBase(tuple.get<0>()), + mUrl(tuple.get<1>()), mPort(tuple.get<2>()), mGroupId(tuple.get<3>()), + mServerType(tuple.get<4>()), mNodeHederaId(tuple.get<5>()), mLastLiveSign(tuple.get<6>()) + { + + } + + NodeServer::~NodeServer() + { + + } + + std::string NodeServer::toString() + { + std::stringstream ss; + + ss << "id: " << getID() << std::endl; + ss << mUrl << ":" << mPort << std::endl; + ss << "group id: " << mGroupId << std::endl; + ss << "server type: " << nodeServerTypeToString((NodeServerType)mServerType) << std::endl; + ss << "node hedera id: " << mNodeHederaId << std::endl; + ss << "last live sign: " << Poco::DateTimeFormatter::format(mLastLiveSign, "%f.%m.%Y %H:%M:%S") << std::endl; + + return ss.str(); + } + + const char* NodeServer::nodeServerTypeToString(NodeServerType type) + { + switch (type) { + case NODE_SERVER_NONE: return "none"; + case NODE_SERVER_GRADIDO_NODE: return "Gradido Node"; + case NODE_SERVER_GRADIDO_COMMUNITY: return "Gradido Community"; + case NODE_SERVER_HEDERA_MAINNET_NODE: return "Hedera Mainnet Node"; + case NODE_SERVER_HEDERA_TESTNET_NODE: return "Hedera Testnet Node"; + default: return ""; + } + } + + Poco::Data::Statement NodeServer::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mUrl), into(mPort), into(mGroupId), into(mServerType), into(mNodeHederaId), into(mLastLiveSign); + + return select; + } + + Poco::Data::Statement NodeServer::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + // typedef Poco::Tuple, int> UserTuple; + select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName() + << " where " << fieldName << " LIKE ?"; + + return select; + } + + Poco::Data::Statement NodeServer::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where url = ? AND port = ? " + , into(mID), use(mUrl), use(mPort); + + unlock(); + return select; + } + + Poco::Data::Statement NodeServer::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (url, port, group_id, server_type, node_hedera_id) VALUES(?,?,?,?,?)" + , use(mUrl), use(mPort), use(mGroupId), use(mServerType), use(mNodeHederaId); + unlock(); + return insert; + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/table/NodeServer.h b/src/cpp/model/table/NodeServer.h new file mode 100644 index 000000000..899be9196 --- /dev/null +++ b/src/cpp/model/table/NodeServer.h @@ -0,0 +1,71 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE + +#include "ModelBase.h" +#include "Poco/Tuple.h" + +namespace model { + namespace table { + + typedef Poco::Tuple NodeServerTuple; + + enum NodeServerType { + NODE_SERVER_NONE, + NODE_SERVER_GRADIDO_NODE, + NODE_SERVER_GRADIDO_COMMUNITY, + NODE_SERVER_HEDERA_MAINNET_NODE, + NODE_SERVER_HEDERA_TESTNET_NODE, + NODE_SERVER_TYPE_COUNT + }; + bool NodeServerIsHederaNode(NodeServerType type); + bool NodeServerHasGroup(NodeServerType type); + + + class NodeServer : public ModelBase + { + public: + NodeServer(); + NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId); + NodeServer(const NodeServerTuple& tuple); + ~NodeServer(); + + // generic db operations + const char* getTableName() const { return "node_servers"; } + std::string toString(); + + static const char* nodeServerTypeToString(NodeServerType type); + + inline void setLastLiveSign(Poco::DateTime lastLiveSign) { std::unique_lock _lock(mSharedMutex); mLastLiveSign = lastLiveSign; } + + inline std::string getUrl() const { return mUrl; } + inline int getPort() const { return mPort; } + inline std::string getUrlWithPort() const { return mUrl + ":" + std::to_string(mPort); } + inline int getGroupId() const { return mGroupId; } + inline NodeServerType getNodeServerType() const { return (NodeServerType)mServerType; } + inline bool isHederaNode() const { return NodeServerIsHederaNode((NodeServerType)mServerType);} + inline bool hasGroup() const {return NodeServerHasGroup((NodeServerType)mServerType);} + inline int getNodeHederaId() const { return mNodeHederaId; } + inline Poco::DateTime getLastLiveSign() const { std::shared_lock _lock(mSharedMutex); return mLastLiveSign; } + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + std::string mUrl; + int mPort; + int mGroupId; + int mServerType; + int mNodeHederaId; + Poco::DateTime mLastLiveSign; + + mutable std::shared_mutex mSharedMutex; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE \ No newline at end of file diff --git a/src/cpsp/adminGroups.cpsp b/src/cpsp/adminGroups.cpsp index e357388af..014591b74 100644 --- a/src/cpsp/adminGroups.cpsp +++ b/src/cpsp/adminGroups.cpsp @@ -34,7 +34,7 @@ //auto groups = controller::Group::load("gdd1"); //std::vector> groups; -%><%@ include file="header.cpsp" %> +%><%@ include file="header_large.cpsp" %> <%= getErrorsHtml() %>
@@ -43,20 +43,20 @@
-
ID
-
Name
-
Alias
-
Url
-
<%= gettext("Description") %>
+
ID
+
Name
+
Alias
+
Url
+
<%= gettext("Description") %>
<% for(auto it = groups.begin(); it != groups.end(); it++) { auto group_model = (*it)->getModel(); %>
-
<%= group_model->getID() %>
-
<%= group_model->getName() %>
-
<%= group_model->getAlias() %>
-
<%= group_model->getUrl() %>
-
<%= group_model->getDescription()%>
+
<%= group_model->getID() %>
+
<%= group_model->getName() %>
+
<%= group_model->getAlias() %>
+
<%= group_model->getUrl() %>
+
<%= group_model->getDescription()%>
<% } %>
diff --git a/src/cpsp/adminNodeServer.cpsp b/src/cpsp/adminNodeServer.cpsp new file mode 100644 index 000000000..e4a0ff49d --- /dev/null +++ b/src/cpsp/adminNodeServer.cpsp @@ -0,0 +1,200 @@ +<%@ page class="AdminNodeServerPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + +#include "../controller/NodeServer.h" +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" +#include "../lib/DataTypeConverter.h" + +%> +<%% + const char* pageName = "Node Server"; + auto sm = SessionManager::getInstance(); + + // add + if(!form.empty()) { + // collect + auto url = form.get("node-server-url", ""); + auto portString = form.get("node-server-port", ""); + auto nodeServerTypeString = form.get("node-server-type", "0"); + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto nodeServerGroupString = form.get("node-server-group", ""); + + int port = 0; + int shardNum = 0; + int realmNum = 0; + int num = 0; + model::table::NodeServerType nodeServerType = model::table::NODE_SERVER_NONE; + int group_id = 0; + + + // validate + if(!sm->isValid(url, VALIDATE_ONLY_URL)) { + addError(new ParamError("Node Server", "Url not valid, must start with http or https", url)); + + } + if(!sm->isValid(portString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server", "Port isn't valid integer")); + } else { + if(DataTypeConverter::strToInt(portString, port) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting port to int")); + } + } + + if(!sm->isValid(nodeServerTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server Type", "not integer")); + } else { + int node_server_type_int = 0; + if(DataTypeConverter::strToInt(nodeServerTypeString, node_server_type_int) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting node server type to int")); + } + if(node_server_type_int < 0 || node_server_type_int >= (int)model::table::NODE_SERVER_TYPE_COUNT) { + addError(new Error("Node Server Type", "invalid value")); + } else { + nodeServerType = (model::table::NodeServerType)node_server_type_int; + } + } + if(model::table::NodeServerIsHederaNode(nodeServerType)) { + + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + } else if(model::table::NodeServerHasGroup(nodeServerType)) { + if(!sm->isValid(nodeServerGroupString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(nodeServerGroupString, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } + } + + + + if(0 == errorCount()) { + int hedera_id_int = 0; + if(NodeServerIsHederaNode(nodeServerType)) { + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + hedera_id_int = hedera_id->getModel()->getID(); + } + + auto node_server = controller::NodeServer::create( + url, port, group_id, (model::table::NodeServerType)nodeServerType, hedera_id_int + ); + if(!node_server->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving Node Server in DB")); + } + } + } + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } + + auto node_servers = controller::NodeServer::listAll(); + + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
+
+
+

Alle Node Server

+
+
+
+
Server Type
+
Url:Port
+
Group / Hedera Id
+
+ <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { + auto node_server_model = (*it)->getModel(); + %> +
+
<%= model::table::NodeServer::nodeServerTypeToString(node_server_model->getNodeServerType()) %>
+
<%= node_server_model->getUrlWithPort() %>
+
+ <% if(node_server_model->isHederaNode()) { + auto hedera_id_model = (*it)->getHederaId()->getModel(); %> + <%= hedera_id_model->toString() %> + <% } else if(node_server_model->hasGroup()){ + auto groupIt = group_indices.find(node_server_model->getGroupId()); + if(groupIt != group_indices.end()) { + auto group_model = groups[groupIt->second]->getModel(); %> + <%= group_model->getName() %> + <% } else { %> + <%= node_server_model->getGroupId() %> + <% } %> + <% } %> +
+
+ <% } %> +
+
+
+

Ein Node Server hinzufügen

+
+
+
+ + + + + + +
+ Nur für Hedera Nodes + + + + +
+
+ Nur für Gradido Nodes + + +
+ + "> +
+
+ +<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/header_large.cpsp b/src/cpsp/header_large.cpsp index 2aa8f5f4b..5f7a8a021 100644 --- a/src/cpsp/header_large.cpsp +++ b/src/cpsp/header_large.cpsp @@ -16,4 +16,14 @@
+
\ No newline at end of file From 5b899366d93816cfb7dd961a9c2f1019479ab753 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 31 Aug 2020 15:05:54 +0200 Subject: [PATCH 017/195] add function to crypto key controller to get directly a KeyPairHedera --- src/cpp/Crypto/KeyPairHedera.cpp | 22 +++++++++++++--------- src/cpp/Crypto/KeyPairHedera.h | 1 + src/cpp/controller/CryptoKey.cpp | 17 +++++++++++++++++ src/cpp/controller/CryptoKey.h | 2 ++ src/cpp/model/table/CryptoKey.h | 5 +++++ 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 0a3bf4bc2..2846e9c43 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -10,13 +10,12 @@ KeyPairHedera::KeyPairHedera() } - -KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) +KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) : mPrivateKey(nullptr) { auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420"); - auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100"); - + auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100"); + auto mm = MemoryManager::getInstance(); if (privateKey) { @@ -46,19 +45,19 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi default: throw std::exception("[KeyPairHedera] invalid private key"); } - + // check public } if (publicKey) { - switch (publicKey->size()) + switch (publicKeySize) { case 32: { // raw public key - memcpy(mPublicKey, *publicKey, publicKey->size()); + memcpy(mPublicKey, publicKey, publicKeySize); break; } case 44: // DER encoded public key - if (0 == sodium_memcmp(*publicKey, *derPrefixPub, derPrefixPub->size())) { - memcpy(mPublicKey, publicKey->data(derPrefixPub->size()), ed25519_pubkey_SIZE); + if (0 == sodium_memcmp(publicKey, *derPrefixPub, derPrefixPub->size())) { + memcpy(mPublicKey, &publicKey[derPrefixPub->size()], ed25519_pubkey_SIZE); } break; default: @@ -75,6 +74,11 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi mm->releaseMemory(derPrefixPriv); mm->releaseMemory(derPrefixPub); } +KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) + : KeyPairHedera(privateKey, publicKey->data(), publicKey->size()) +{ + +} KeyPairHedera::~KeyPairHedera() { diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 115beebdb..7f0b7f3bc 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -22,6 +22,7 @@ public: //! \param privateKey: copy //! \param publicKey: copy //! + KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); ~KeyPairHedera(); diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 2e7d343ec..093a21e69 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -62,6 +62,23 @@ namespace controller { return nullptr; } + KeyPairHedera* CryptoKey::getKeyPair(Poco::AutoPtr user) + { + auto model = getModel(); + auto password = user->getPassword(); + auto mm = MemoryManager::getInstance(); + if (!password || !model->hasPrivateKeyEncrypted()) { + return nullptr; + } + MemoryBin* clearPassword = nullptr; + if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { + return nullptr; + } + KeyPairHedera* key_pair = new KeyPairHedera(clearPassword, model->getPublicKey(), model->getPublicKeySize()); + mm->releaseMemory(clearPassword); + return key_pair; + } + } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index 6e4e110bb..12bb40e70 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -27,6 +27,8 @@ namespace controller { inline Poco::AutoPtr getModel() { return _getModel(); } + KeyPairHedera* getKeyPair(Poco::AutoPtr user); + protected: CryptoKey(model::table::CryptoKey* dbModel); diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index 58d6df5dc..7e50fc728 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -24,6 +24,11 @@ namespace model { const char* getTableName() const { return "crypto_keys"; } std::string toString(); + inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } + + inline bool hasPrivateKeyEncrypted() const { return !mPrivateKey.isNull(); } + inline const std::vector& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); } static const char* typeToString(KeyType type); protected: From 71edd964ac10df0b612f67e2f46f54e33a192ae7 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 31 Aug 2020 19:55:56 +0200 Subject: [PATCH 018/195] compose hedera query to get balance, update CMakeLists.txt for adding missing libs for grpc --- CMakeLists.txt | 27 +++++- src/cpp/Crypto/KeyPairHedera.h | 1 + .../HTTPInterface/AdminHederaAccountPage.cpp | 68 +++++++++++---- src/cpp/controller/CryptoKey.cpp | 6 +- src/cpp/controller/CryptoKey.h | 2 +- src/cpp/controller/HederaAccount.cpp | 37 +++++++++ src/cpp/controller/HederaAccount.h | 5 +- src/cpp/controller/HederaId.cpp | 8 ++ src/cpp/controller/HederaId.h | 5 ++ src/cpp/controller/NodeServer.h | 4 +- src/cpp/main.cpp | 13 ++- src/cpp/model/hedera/Query.cpp | 83 +++++++++++++++++++ src/cpp/model/hedera/Query.h | 39 +++++++++ src/cpp/model/table/HederaAccount.cpp | 9 ++ src/cpp/model/table/HederaAccount.h | 9 +- src/cpp/model/table/HederaId.h | 4 + src/cpp/model/table/NodeServer.h | 3 +- 17 files changed, 295 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b16d3bb4e..f246d7e52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,9 +95,30 @@ find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-conne find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build/Debug" REQUIRED) set(GRPC_PATH "dependencies/grpc/_build/Debug") +set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/Debug") +set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") +set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) -set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION}) +find_library(GRPC_LIB grpc PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_ERROR_DETAILS grpc++_error_details PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) + +find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) +set(GRPC_LIBS + ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} + ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} + ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} + ${GRPC_CARES} ${GRPC_BORING_SSL_CRYPTO} ${GRPC_BORING_SSL_SSL} +) + set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") #set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") @@ -142,7 +163,9 @@ include_directories( endif(WIN32) -target_link_libraries(Gradido_LoginServer ${CONAN_LIBS} ${IROHA_ED25519}) +add_subdirectory("dependencies/grpc/third_party/abseil-cpp") + +target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 7f0b7f3bc..a3e4337e5 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -37,6 +37,7 @@ public: inline const unsigned char* getPublicKey() const { return mPublicKey; } MemoryBin* getPublicKeyCopy() const; + const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;} inline bool isTheSame(const KeyPairHedera& b) const { return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 0de7a6922..0169083ef 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -14,6 +14,10 @@ #include "../lib/DataTypeConverter.h" #include "../SingletonManager/SessionManager.h" +#include "../ServerConfig.h" + +#include "Poco/URI.h" + #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" #include "../ServerConfig.h" @@ -33,15 +37,42 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 20 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Poco::URI uri(request.getURI()); + auto uri_query = uri.getQueryParameters(); + std::string action = ""; + std::string account_id_from_query; + if(uri_query[0].first == "action") { + action = uri_query[0].second; + } + if(uri_query[1].first == "account_id") { + account_id_from_query = uri_query[1].second; + } + for(auto it = uri_query.begin(); it != uri_query.end(); it++) { + printf("first: %s, second: %s\n", it->first.data(), it->second.data()); + } + + if(action == "updateBalance") { + int account_id = 0; + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); + } else { + auto hedera_account = controller::HederaAccount::load("id", account_id); + if(!hedera_account.size() || hedera_account[0].isNull()) { + addError(new Error("Action Update Balance", "hedera id not found")); + } else { + hedera_account[0]->updateBalanceFromHedera(user); + } + } + } // add - if(!form.empty()) { + else if(!form.empty()) { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); @@ -196,7 +227,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; @@ -210,32 +241,41 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
Balance
\n"; responseStream << "\t\t\t\t
Server Type
\n"; responseStream << "\t\t\t\t
Last Updated
\n"; + responseStream << "\t\t\t\t
Aktionen
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t"; -#line 134 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); + auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t
"; -#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
\n"; responseStream << "\t\t\t\t\t
"; -#line 140 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 173 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 141 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
\n"; + responseStream << "\t\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t"; -#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; @@ -255,21 +295,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 093a21e69..3fabc25c5 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -62,19 +62,21 @@ namespace controller { return nullptr; } - KeyPairHedera* CryptoKey::getKeyPair(Poco::AutoPtr user) + std::unique_ptr CryptoKey::getKeyPair(Poco::AutoPtr user) { auto model = getModel(); auto password = user->getPassword(); auto mm = MemoryManager::getInstance(); if (!password || !model->hasPrivateKeyEncrypted()) { + printf("[CryptoKey::getKeyPair] return null, password empty or no private key\n"); return nullptr; } MemoryBin* clearPassword = nullptr; if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { + printf("[CryptoKey::getKeyPair] return null, error decrypting\n"); return nullptr; } - KeyPairHedera* key_pair = new KeyPairHedera(clearPassword, model->getPublicKey(), model->getPublicKeySize()); + auto key_pair = std::make_unique(clearPassword, model->getPublicKey(), model->getPublicKeySize()); mm->releaseMemory(clearPassword); return key_pair; } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index 12bb40e70..fc69d042c 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -27,7 +27,7 @@ namespace controller { inline Poco::AutoPtr getModel() { return _getModel(); } - KeyPairHedera* getKeyPair(Poco::AutoPtr user); + std::unique_ptr getKeyPair(Poco::AutoPtr user); protected: diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 9f4ff5b40..564752f72 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -1,5 +1,9 @@ #include "HederaAccount.h" +#include "NodeServer.h" +#include "CryptoKey.h" +#include "../model/hedera/Query.h" +#include "HederaRequest.h" namespace controller { @@ -69,5 +73,38 @@ namespace controller { return resultVector; } + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user) + { + static const char* functionName = "HederaAccount::updateBalanceFromHedera"; + + if (user.isNull() || !user->getModel()) { + printf("[%s] invalid user\n", functionName); + return false; + } + + auto account_model = getModel(); + auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); + auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); + if (crypto_key.isNull()) { + printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); + return false; + } + auto hedera_key_pair = crypto_key->getKeyPair(user); + if (!hedera_key_pair) { + printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); + return false; + } + auto query = model::hedera::Query::getBalance(mHederaID, hedera_node); + if (!query) { + printf("[%s] error creating query\n", functionName); + } + query->sign(std::move(hedera_key_pair)); + + HederaRequest request; + request.request(query); + + return false; + } + } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index dd4c97435..1a3fd9ace 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -1,7 +1,8 @@ #ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE #define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE -#include "../controller/HederaId.h" +#include "HederaId.h" +#include "User.h" #include "../model/table/HederaAccount.h" #include "Poco/SharedPtr.h" @@ -26,6 +27,8 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } + bool updateBalanceFromHedera(Poco::AutoPtr user); + protected: HederaAccount(model::table::HederaAccount* dbModel); Poco::AutoPtr mHederaID; diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index e6d281907..ce171a7a8 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -29,4 +29,12 @@ namespace controller { } return nullptr; } + + void HederaId::copyToProtoAccountId(proto::AccountID* protoAccountId) const + { + auto model = getModel(); + protoAccountId->set_shardnum(model->getShardNum()); + protoAccountId->set_realmnum(model->getRealmNum()); + protoAccountId->set_accountnum(model->getNum()); + } } \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index f02e69373..ae9296a43 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -7,6 +7,8 @@ #include "TableControllerBase.h" +#include "../proto/hedera/BasicTypes.pb.h" + namespace controller { class HederaId : public TableControllerBase { @@ -21,6 +23,9 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::HederaId* getModel() const { return _getModel(); } + + void copyToProtoAccountId(proto::AccountID* protoAccountId) const; protected: diff --git a/src/cpp/controller/NodeServer.h b/src/cpp/controller/NodeServer.h index 5a2750194..8cc4b4e23 100644 --- a/src/cpp/controller/NodeServer.h +++ b/src/cpp/controller/NodeServer.h @@ -15,6 +15,8 @@ namespace controller { NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {} NodeServerConnection() :port(0) {}; + std::string getUrlWithPort() const { return url + ":" + std::to_string(port); } + bool isValid() { return url != "" && port; } std::string url; int port; @@ -35,7 +37,7 @@ namespace controller { static std::vector> load(model::table::NodeServerType type, int group_id = 0); static std::vector> listAll(); // pick server randomly - NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0); + static NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 715352f91..910db09ff 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -13,6 +13,7 @@ #include "model/table/EmailOptIn.h" #include "Poco/DateTimeParser.h" +#include #ifndef _TEST_BUILD @@ -35,8 +36,8 @@ int main(int argc, char** argv) ServerConfig::g_versionString = Poco::DateTimeFormatter::format(buildDateTime, "0.%y.%m.%d"); //ServerConfig::g_versionString = "0.20.KW13.02"; printf("Version: %s\n", ServerConfig::g_versionString.data()); - printf("User size: %d Bytes, Session size: %d Bytes\n", sizeof(User), sizeof(Session)); - printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", sizeof(model::table::User), sizeof(model::table::EmailOptIn)); + printf("User size: %d Bytes, Session size: %d Bytes\n", (int)sizeof(User), (int)sizeof(Session)); + printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", (int)sizeof(model::table::User), (int)sizeof(model::table::EmailOptIn)); // load word lists if (!ServerConfig::loadMnemonicWordLists()) { @@ -49,8 +50,12 @@ int main(int argc, char** argv) printf("test passphrase generation and transformation failed\n"); return -3; } - + grpc_init(); + Gradido_LoginServer app; - return app.run(argc, argv); + auto result = app.run(argc, argv); + + grpc_shutdown(); + return result; } #endif \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index e69de29bb..d47449bc6 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -0,0 +1,83 @@ +#include "Query.h" +#include "Poco/Timestamp.h" +#include "../../SingletonManager/MemoryManager.h" + +namespace model { + namespace hedera { + + Query::Query(const controller::NodeServerConnection& connection) + : mConnection(connection) + { + + } + + Query::~Query() + { + + } + + Query* Query::getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection) + { + + assert(!accountId.isNull() && accountId->getModel()); + + auto query = new Query(connection); + auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance(); + accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); + auto query_header = get_account_balance->mutable_header(); + query_header->set_responsetype(proto::ANSWER_ONLY); + auto transaction = query_header->mutable_payment(); + //auto transaction_body = transaction->mutable_body(); + // body content + // transaction id + auto transaction_id = query->mTransactionBody.mutable_transactionid(); + auto timestamp = transaction_id->mutable_transactionvalidstart(); + Poco::Timestamp now; + auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 + timestamp->set_seconds(now.epochTime()); + timestamp->set_nanos(microseconds * 1000); + accountId->copyToProtoAccountId(transaction_id->mutable_accountid()); + // + // sdk default, but can be changed + query->mTransactionBody.set_transactionfee(100000000); + auto valid_duration = query->mTransactionBody.mutable_transactionvalidduration(); + // maximal 2 minutes + valid_duration->set_seconds(120); + auto crypto_transfer = query->mTransactionBody.mutable_cryptotransfer(); + auto transfer_list = crypto_transfer->mutable_transfers(); + auto account_amounts = transfer_list->mutable_accountamounts(); + account_amounts->Add(); + auto account_amount = account_amounts->Mutable(0); + account_amount->set_amount(0); + connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); + + return query; + } + + bool Query::sign(std::unique_ptr keyPairHedera) + { + auto mm = MemoryManager::getInstance(); + auto body_bytes = mTransactionBody.SerializeAsString(); + auto transaction = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header()->mutable_payment(); + transaction->set_bodybytes(body_bytes.data()); + auto signature_map = transaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_pairs->Add(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + + return true; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index e69de29bb..8dff35024 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -0,0 +1,39 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H + +/*! + * @author: Dario Rekowski + * + * @date: 31.08.20 + * + * @brief: class for put together hedera querys (ask for state data, not a transaction, but needs a payment transaction) + * +*/ + +#include "../../proto/hedera/Query.pb.h" +#include "../../controller/NodeServer.h" +#include "../../Crypto/KeyPairHedera.h" + +namespace model { + namespace hedera { + class Query + { + public: + ~Query(); + static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); + bool sign(std::unique_ptr keyPairHedera); + + inline const proto::Query* getProtoQuery() const { return &mQueryProto; } + inline std::string getConnectionString() const { return mConnection.getUrlWithPort(); } + + protected: + Query(const controller::NodeServerConnection& connection); + proto::Query mQueryProto; + proto::TransactionBody mTransactionBody; + controller::NodeServerConnection mConnection; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 06538fdcb..1485ff554 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -53,6 +53,15 @@ namespace model { } } + NodeServerType HederaAccount::networkTypeToNodeServerType(HederaNetworkType type) + { + switch (type) { + case HEDERA_MAINNET: return NODE_SERVER_HEDERA_MAINNET_NODE; + case HEDERA_TESTNET: return NODE_SERVER_HEDERA_TESTNET_NODE; + default: return NODE_SERVER_TYPE_NONE; + } + } + Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index c38af1df1..4d4dd6575 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -4,6 +4,8 @@ #include "ModelBase.h" #include "Poco/Tuple.h" +#include "NodeServer.h" + namespace model { namespace table { @@ -12,7 +14,7 @@ namespace model { enum HederaNetworkType { HEDERA_MAINNET, HEDERA_TESTNET, - HEDERA_NET_COUNT + HEDERA_NET_COUNT, }; class HederaAccount : public ModelBase @@ -28,13 +30,16 @@ namespace model { std::string toString(); static const char* hederaNetworkTypeToString(HederaNetworkType type); + static NodeServerType networkTypeToNodeServerType(HederaNetworkType type); - inline int getAccountHederaId() { return mAccountHederaId; } + inline int getAccountHederaId() const { return mAccountHederaId; } + inline int getCryptoKeyId() const { return mAccountKeyId; } inline Poco::UInt64 getBalance() { return mBalance; } inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } inline HederaNetworkType getNetworkType() { return (HederaNetworkType)mType; } + inline std::string getUpdatedString() { return Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S"); } diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index 8de69c2a9..9dc2029bc 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -21,6 +21,10 @@ namespace model { //! \brief check if hedera id already in db, then return id, else insert in db and return int getID(); + inline Poco::UInt64 getShardNum() const { return mShardNum; } + inline Poco::UInt64 getRealmNum() const { return mRealmNum; } + inline Poco::UInt64 getNum() const { return mNum; } + protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/NodeServer.h b/src/cpp/model/table/NodeServer.h index 899be9196..4e592c822 100644 --- a/src/cpp/model/table/NodeServer.h +++ b/src/cpp/model/table/NodeServer.h @@ -15,7 +15,8 @@ namespace model { NODE_SERVER_GRADIDO_COMMUNITY, NODE_SERVER_HEDERA_MAINNET_NODE, NODE_SERVER_HEDERA_TESTNET_NODE, - NODE_SERVER_TYPE_COUNT + NODE_SERVER_TYPE_COUNT, + NODE_SERVER_TYPE_NONE }; bool NodeServerIsHederaNode(NodeServerType type); bool NodeServerHasGroup(NodeServerType type); From 43dd1a5082a4365cb0f27143cbf4b48eaffc000c Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:06:20 +0200 Subject: [PATCH 019/195] update grpc to new version, update some things they don't work for create the first query to hedera --- CMakeLists.txt | 7 ++- skeema/gradido_login/crypto_keys.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 5 ++ .../HTTPInterface/AdminHederaAccountPage.cpp | 49 ++++++++++--------- src/cpp/controller/CryptoKey.cpp | 4 ++ src/cpp/controller/HederaAccount.cpp | 12 ++++- src/cpp/controller/HederaAccount.h | 2 +- src/cpp/controller/NodeServer.cpp | 15 +++++- src/cpp/controller/NodeServer.h | 6 ++- src/cpp/lib/DataTypeConverter.h | 1 + src/cpp/model/hedera/Query.h | 2 +- 11 files changed, 73 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f246d7e52..6a24af9a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ set(GRPC_PATH "dependencies/grpc/_build/Debug") set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/Debug") set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") +set(GRPC_RE2_PATH "dependencies/grpc/_build/third_party/re2/Debug") find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) @@ -110,13 +111,17 @@ find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_RE2 re2 ${GRPC_RE2_PATH} REQUIRED) find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} - ${GRPC_CARES} ${GRPC_BORING_SSL_CRYPTO} ${GRPC_BORING_SSL_SSL} + ${GRPC_CARES} + ${GRPC_BORING_SSL_CRYPTO} + ${GRPC_BORING_SSL_SSL} + ${GRPC_RE2} ) set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index c90750ae3..c79987755 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,6 +1,6 @@ CREATE TABLE `crypto_keys` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `private_key` varbinary(64) NOT NULL, + `private_key` binary(80) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`), diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 2846e9c43..27d9731a7 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -162,8 +162,13 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtrencrypt(mPrivateKey, &encryptedKey)) { + auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encryptedKey); + printf("[KeyPairHedera::getCryptedPrivKey] encryptet private key hex: %s\n", encrypted_private_key_hex_string.data()); return encryptedKey; } else { diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 0169083ef..a9d4165c3 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -48,16 +48,14 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto uri_query = uri.getQueryParameters(); std::string action = ""; std::string account_id_from_query; - if(uri_query[0].first == "action") { - action = uri_query[0].second; + if(uri_query.size() >= 2) { + if(uri_query[0].first == "action") { + action = uri_query[0].second; + } + if(uri_query[1].first == "account_id") { + account_id_from_query = uri_query[1].second; + } } - if(uri_query[1].first == "account_id") { - account_id_from_query = uri_query[1].second; - } - for(auto it = uri_query.begin(); it != uri_query.end(); it++) { - printf("first: %s, second: %s\n", it->first.data(), it->second.data()); - } - if(action == "updateBalance") { int account_id = 0; if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { @@ -67,7 +65,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { - hedera_account[0]->updateBalanceFromHedera(user); + hedera_account[0]->updateBalanceFromHedera(user, this); } } } @@ -227,7 +225,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 150 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; @@ -244,38 +242,38 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
Aktionen
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t"; -#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t
"; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
\n"; responseStream << "\t\t\t\t\t
"; -#line 173 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
\n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t"; -#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; @@ -283,7 +281,10 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t

Einen neuen Account anlegen

\n"; responseStream << "\t
\n"; responseStream << "\t
\n"; - responseStream << "\t\t
\n"; + responseStream << "\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; @@ -295,21 +296,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
\n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 3fabc25c5..79d68a62e 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -1,6 +1,7 @@ #include "CryptoKey.h" #include "../SingletonManager/ErrorManager.h" +#include "../lib/DataTypeConverter.h" namespace controller { @@ -72,6 +73,9 @@ namespace controller { return nullptr; } MemoryBin* clearPassword = nullptr; + auto encrypted_private_key = model->getPrivateKeyEncrypted(); + auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key); + printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data()); if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { printf("[CryptoKey::getKeyPair] return null, error decrypting\n"); return nullptr; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 564752f72..6172db46c 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user) + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -101,7 +101,15 @@ namespace controller { query->sign(std::move(hedera_key_pair)); HederaRequest request; - request.request(query); + try { + request.request(query); + } + catch (Poco::Exception& ex) { + printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); + } + if (errorReceiver) { + errorReceiver->getErrors(&request); + } return false; } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 1a3fd9ace..7f08adddc 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -27,7 +27,7 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user); + bool updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/NodeServer.cpp b/src/cpp/controller/NodeServer.cpp index 6096b2839..625e61dad 100644 --- a/src/cpp/controller/NodeServer.cpp +++ b/src/cpp/controller/NodeServer.cpp @@ -1,9 +1,21 @@ #include "NodeServer.h" #include "../SingletonManager/ErrorManager.h" #include "../SingletonManager/ConnectionManager.h" +#include "Poco/RegularExpression.h" namespace controller { + Poco::RegularExpression g_filterHttp("^https?://"); + + std::string NodeServerConnection::getUriWithPort() const + { + std::string protocol; + g_filterHttp.extract(url, protocol); + return url.substr(protocol.size()) + ":" + std::to_string(port); + } + + + NodeServer::NodeServer(model::table::NodeServer* dbModel) { @@ -74,12 +86,13 @@ namespace controller { if (model::table::NodeServerIsHederaNode(type)) { select << ", node_hedera_id"; } - select << " from node_servers ORDER BY RAND() LIMIT 1" + select << " from node_servers where server_type = ? ORDER BY RAND() LIMIT 1" , Poco::Data::Keywords::into(result.url) , Poco::Data::Keywords::into(result.port); if (model::table::NodeServerIsHederaNode(type)) { select, Poco::Data::Keywords::into(hedera_node_id); } + select , Poco::Data::Keywords::bind((int)type); try { if (1 == select.execute()) { if (model::table::NodeServerIsHederaNode(type)) { diff --git a/src/cpp/controller/NodeServer.h b/src/cpp/controller/NodeServer.h index 8cc4b4e23..6945ac949 100644 --- a/src/cpp/controller/NodeServer.h +++ b/src/cpp/controller/NodeServer.h @@ -15,7 +15,11 @@ namespace controller { NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {} NodeServerConnection() :port(0) {}; - std::string getUrlWithPort() const { return url + ":" + std::to_string(port); } + // with http:// or https:// + inline std::string getUrlWithPort() const { return url + ":" + std::to_string(port); } + + // without http:// or https:// + std::string getUriWithPort() const; bool isValid() { return url != "" && port; } std::string url; diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index 46a767d97..0dad46954 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -31,6 +31,7 @@ namespace DataTypeConverter { std::string binToHex(const unsigned char* data, size_t size); std::string binToHex(const Poco::Nullable& nullableBin); inline std::string binToHex(const MemoryBin* data) { return binToHex(data->data(), data->size());} + inline std::string binToHex(const std::vector& data) { return binToHex(data.data(), data.size()); } //! \param pubkey pointer to array with crypto_sign_PUBLICKEYBYTES size std::string pubkeyToHex(const unsigned char* pubkey); diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index 8dff35024..ad9af855a 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -24,7 +24,7 @@ namespace model { bool sign(std::unique_ptr keyPairHedera); inline const proto::Query* getProtoQuery() const { return &mQueryProto; } - inline std::string getConnectionString() const { return mConnection.getUrlWithPort(); } + inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } protected: Query(const controller::NodeServerConnection& connection); From c968a58cfa758655966b12848b2c88fe7e3f37e5 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:36:50 +0200 Subject: [PATCH 020/195] add some missing files --- skeema/gradido_login/node_servers.sql | 10 + src/cpp/HTTPInterface/AdminTopicPage.cpp | 128 +++++++++++ src/cpp/HTTPInterface/AdminTopicPage.h | 20 ++ .../HTTPInterface/PassphrasedTransaction.cpsp | 162 ++++++++++++++ src/cpp/controller/HederaRequest.cpp | 39 ++++ src/cpp/controller/HederaRequest.h | 39 ++++ src/cpsp/adminHederaAccount.cpsp | 203 ++++++++++++++++++ 7 files changed, 601 insertions(+) create mode 100644 skeema/gradido_login/node_servers.sql create mode 100644 src/cpp/HTTPInterface/AdminTopicPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminTopicPage.h create mode 100644 src/cpp/HTTPInterface/PassphrasedTransaction.cpsp create mode 100644 src/cpp/controller/HederaRequest.cpp create mode 100644 src/cpp/controller/HederaRequest.h create mode 100644 src/cpsp/adminHederaAccount.cpsp diff --git a/skeema/gradido_login/node_servers.sql b/skeema/gradido_login/node_servers.sql new file mode 100644 index 000000000..88e4d8ac3 --- /dev/null +++ b/skeema/gradido_login/node_servers.sql @@ -0,0 +1,10 @@ +CREATE TABLE `node_servers` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `url` VARCHAR(255) NOT NULL, + `port` INT UNSIGNED NOT NULL, + `group_id` INT UNSIGNED NULL DEFAULT '0', + `server_type` INT UNSIGNED NOT NULL DEFAULT '0', + `node_hedera_id` INT UNSIGNED NULL DEFAULT '0', + `last_live_sign` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00', + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/HTTPInterface/AdminTopicPage.cpp b/src/cpp/HTTPInterface/AdminTopicPage.cpp new file mode 100644 index 000000000..d8926093e --- /dev/null +++ b/src/cpp/HTTPInterface/AdminTopicPage.cpp @@ -0,0 +1,128 @@ +#include "AdminTopicPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +AdminTopicPage::AdminTopicPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + + const char* pageName = "Topic"; + + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t
"; + // end include header_large.cpsp + responseStream << "\n"; +#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t

Topic Admin Page

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "\t\n"; + responseStream << "
\n"; + // begin include footer.cpsp + responseStream << "
\n"; + responseStream << "

Copyright © Gradido 2020

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "

Login Server in Entwicklung

\n"; + responseStream << "

Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminTopicPage.h b/src/cpp/HTTPInterface/AdminTopicPage.h new file mode 100644 index 000000000..b02e5856c --- /dev/null +++ b/src/cpp/HTTPInterface/AdminTopicPage.h @@ -0,0 +1,20 @@ +#ifndef AdminTopicPage_INCLUDED +#define AdminTopicPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminTopicPage: public SessionHTTPRequestHandler +{ +public: + AdminTopicPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminTopicPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp b/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp new file mode 100644 index 000000000..debc1f296 --- /dev/null +++ b/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp @@ -0,0 +1,162 @@ +<%@ page class="PassphrasedTransaction" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="PageRequestMessagedHandler" %> +<%@ header include="PageRequestMessagedHandler.h" %> +<%! +#include "../SingletonManager/MemoryManager.h" +#include "../SingletonManager/SessionManager.h" +#include "../Crypto/KeyPair.h" +#include "../ServerConfig.h" + +#include "Poco/JSON/Object.h" +#include "Poco/JSON/Parser.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" + +enum PageState { + PAGE_STATE_INPUT, + PAGE_STATE_SUCCESS +}; +%> +<%% + std::string pageName = "Gradidos mit Passphrase überweisen"; + PageState state = PAGE_STATE_INPUT; + Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + std::string errorString =""; + + if(!form.empty()) { + auto passphrase = form.get("passphrase", ""); + bool passphraseValid = User::validatePassphrase(passphrase, &wordSource); + bool keysGenerated = false; + KeyPair keys; + if(!passphraseValid) + { + addError(new Error("Passphrase", "Fehler beim validieren der Passphrase")); + } + else + { + keysGenerated = keys.generateFromPassphrase(passphrase.data(), wordSource); + if(!keysGenerated) + { + addError(new Error("Passphrase", "Konnte keine Keys aus der Passphrase generieren")); + } + } + if(passphraseValid && keysGenerated) + { + // create session only for transaction + int session_id = 0; + auto session = sm->getNewSession(&session_id); + // create payload + Poco::JSON::Object requestJson; + Poco::JSON::Object pubkeys; + pubkeys.set("sender", keys.getPubkeyHex()); + pubkeys.set("receiver", form.get("recevier", "")); + requestJson.set("method", "moveTransaction"); + requestJson.set("pubkeys", pubkeys); + requestJson.set("memo", form.get("memo", "")); + requestJson.set("session_id", session_id); + + printf("[PassphrasedTransaction] prepare request\n"); + + // send to php server + Poco::Net::HTTPSClientSession httpsClientSession(ServerConfig::g_php_serverHost, 443); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); + + request.setChunkedTransferEncoding(true); + std::ostream& requestStream = httpsClientSession.sendRequest(request); + requestJson.stringify(requestStream); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = httpsClientSession.receiveResponse(response); + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + + printf("[PassphrasedTransaction] parse request result\n"); + try { + parsedJson = jsonParser.parse(responseStringStream); + + Poco::JSON::Object object = *parsedJson.extract(); + auto jsonState = object.get("state"); + std::string stateString = jsonState.convert(); + if (stateString == "error") { + addError(new Error("Transfer", "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError("php server", "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError("php server", "details:", object.get("details").convert().data())); + } + } else if(stateString == "success") { + printf("[PassphrasedTransaction] request success, wait on transaction ready\n"); + auto currentActiveTransaction = session->getNextReadyTransaction(); + while(currentActiveTransaction.isNull()) { + Poco::Thread::sleep(10); + currentActiveTransaction = session->getNextReadyTransaction(); + } + if(!currentActiveTransaction->isTransfer()) { + addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); + } else { + //auto signing = new SigningTransaction(currentActiveTransaction, user); + printf("[PassphrasedTransaction] cannot sign, implementation missing\n"); + /*if(!signing->run()) { + + } else { + addError(new Error("Transaction", "Fehler beim signieren, bitter erneut versuchen")); + }*/ + // remove transaction from list + //mSession->finalizeTransaction(true, true); + } + } + } + catch (Poco::Exception& ex) { + //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); + addError(new ParamError("Transfer", "Fehler beim erstellen der Transaktion, bitte erneut versuchen", ex.displayText().data())); + errorString = responseStringStream.str(); + sm->releaseSession(session); + session = nullptr; + } + if(session) { + sm->releaseSession(session); + } + } + } + + +%><%@ include file="header_old.cpsp" %> +<% if("" == errorString) { %> + <%= errorString %> +<% } %> +
+ <%= getErrorsHtml() %> + <% if(PAGE_STATE_INPUT == state) { %> + +
+
+

+

+

+

+

+ + "/> +

+

+
+
+ <% } else if(PAGE_STATE_SUCCESS == state) { %> +

Gradidos wurden erfolgreich überwiesen.

+ Weitere Gradidos überweisen + <% } %> +
+<%@ include file="footer.cpsp" %> diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp new file mode 100644 index 000000000..ec1c6c2a0 --- /dev/null +++ b/src/cpp/controller/HederaRequest.cpp @@ -0,0 +1,39 @@ +#include "HederaRequest.h" +#include "../proto/hedera/CryptoService.grpc.pb.h" + +#include +#include +#include +#include +#include + +HederaRequest::HederaRequest() +{ + +} + +HederaRequest::~HederaRequest() +{ + +} + +HederaRequestReturn HederaRequest::request(model::hedera::Query* query) +{ + auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); + grpc::ClientContext context; + std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + + std::chrono::milliseconds(100); + context.set_deadline(deadline); + + auto proto_query = query->getProtoQuery(); + proto::Response* response = nullptr; + if (proto_query->has_cryptogetaccountbalance()) { + auto stub = proto::CryptoService::NewStub(channel); + auto connect_string = query->getConnectionString(); + printf("try connection to hedera with: %s\n", connect_string.data()); + auto status = stub->cryptoGetBalance(&context, *proto_query, response); + addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); + printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); + } + return HEDERA_REQUEST_RETURN_OK; +} \ No newline at end of file diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h new file mode 100644 index 000000000..692215f8d --- /dev/null +++ b/src/cpp/controller/HederaRequest.h @@ -0,0 +1,39 @@ +#ifndef __GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_ +#define __GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_ +/*! +* +* \author: Dario Rekowski +* +* \date: 31.08.2020 +* +* \brief: Class for Hedera Requests +* +*/ + +#include "../controller/NodeServer.h" +#include "../model/hedera/Query.h" + +enum HederaRequestReturn +{ + HEDERA_REQUEST_RETURN_OK, + HEDERA_REQUEST_RETURN_PARSE_ERROR, + HEDERA_REQUEST_RETURN_ERROR, + HEDERA_REQUEST_CONNECT_ERROR +}; + +// NodeServerConnection +class HederaRequest : public ErrorList +{ +public: + HederaRequest(); + ~HederaRequest(); + + HederaRequestReturn request(model::hedera::Query* query); + +protected: + +}; + + +#endif //__GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_ +// \ No newline at end of file diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp new file mode 100644 index 000000000..b4fd1f485 --- /dev/null +++ b/src/cpsp/adminHederaAccount.cpsp @@ -0,0 +1,203 @@ +<%@ page class="AdminHederaAccountPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + +#include "../controller/HederaAccount.h" +#include "../controller/HederaId.h" +#include "../controller/CryptoKey.h" +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" + +#include "../ServerConfig.h" + +#include "Poco/URI.h" + +%> +<%% + const char* pageName = "Hedera Account"; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + auto user = mSession->getNewUser(); + + Poco::URI uri(request.getURI()); + auto uri_query = uri.getQueryParameters(); + std::string action = ""; + std::string account_id_from_query; + if(uri_query.size() >= 2) { + if(uri_query[0].first == "action") { + action = uri_query[0].second; + } + if(uri_query[1].first == "account_id") { + account_id_from_query = uri_query[1].second; + } + } + if(action == "updateBalance") { + int account_id = 0; + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); + } else { + auto hedera_account = controller::HederaAccount::load("id", account_id); + if(!hedera_account.size() || hedera_account[0].isNull()) { + addError(new Error("Action Update Balance", "hedera id not found")); + } else { + hedera_account[0]->updateBalanceFromHedera(user, this); + } + } + } + // add + else if(!form.empty()) { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); + } + if(0 == errorCount()) { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); + } + + } + + // list accounts + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
+
+
+

Deine Hedera Accounts

+
+
+
+
Hedera Id
+
Balance
+
Server Type
+
Last Updated
+
Aktionen
+
+ <% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { + auto hedera_account_model = (*it)->getModel(); + auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + %> +
+
<%= (*it)->getHederaId()->getModel()->toString() %>
+
<%= hedera_account_model->getBalanceDouble() %> hbar
+
<%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
+
<%= hedera_account_model->getUpdatedString() %>
+
+ +
+ <% } %> +
+
+
+

Einen neuen Account anlegen

+
+
+
+ + + + + + + + + + + "> +
+
+<%@ include file="footer.cpsp" %> From e866e53d60f3507ffd328b3e9d95766915f675fa Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:40:19 +0200 Subject: [PATCH 021/195] missing class name --- dependencies/grpc | 2 +- src/cpp/model/table/ModelBase.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies/grpc b/dependencies/grpc index f57a0619b..7d7e45676 160000 --- a/dependencies/grpc +++ b/dependencies/grpc @@ -1 +1 @@ -Subproject commit f57a0619bc5697ea98c2d5b2c983c7024f43a5db +Subproject commit 7d7e4567625db7cfebf8969a225948097a3f9f89 diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 82e5c273e..04ce4ffe4 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -149,7 +149,7 @@ namespace model { } template - std::vector loadAllFromDB() + std::vector ModelBase::loadAllFromDB() { std::vector results; Poco::ScopedLock _lock(mWorkMutex); From 3e3bd6d012c12943932764b27bec160b504d09fb Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:47:19 +0200 Subject: [PATCH 022/195] fix error only occuring in linux --- src/cpp/controller/Group.cpp | 3 ++- src/cpp/controller/HederaAccount.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cpp/controller/Group.cpp b/src/cpp/controller/Group.cpp index 2d809da07..f835e6986 100644 --- a/src/cpp/controller/Group.cpp +++ b/src/cpp/controller/Group.cpp @@ -42,7 +42,8 @@ namespace controller { // work around for not working call to loadAllFromDB auto cm = ConnectionManager::getInstance(); - Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); select << "SELECT id, alias, name, url, description FROM " << db->getTableName() , Poco::Data::Keywords::into(group_list); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 6172db46c..58c71b5ec 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -46,10 +46,11 @@ namespace controller { auto db = new model::table::HederaAccount(); std::vector group_list; // throw an unresolved external symbol error - //group_list = db->loadAllFromDB(); + group_list = db->loadAllFromDB(); // work around for not working call to loadAllFromDB - auto cm = ConnectionManager::getInstance(); + /*auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); select << "SELECT id, alias, name, url, description FROM " << db->getTableName() @@ -62,7 +63,7 @@ namespace controller { catch (Poco::Exception& ex) { printf("[Group::listAll] poco exception: %s\n", ex.displayText().data()); } - // work around end + //*/ //work around end std::vector> resultVector; resultVector.reserve(group_list.size()); From 72b4389be450a9f4ad08c3b0985612bef4fd328e Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 2 Sep 2020 14:06:23 +0200 Subject: [PATCH 023/195] use protobuf from inside grpc, even for parsing protofiles for easy version switch, fix html error --- CMakeLists.txt | 15 ++++++++++++++- README | 1 + conanfile.txt | 1 - compile_proto.sh => parse_proto.sh | 0 .../HTTPInterface/AdminHederaAccountPage.cpp | 17 ++++++++--------- src/cpp/controller/HederaAccount.cpp | 1 - src/cpp/controller/HederaRequest.cpp | 10 +++++++++- src/cpp/model/hedera/Query.cpp | 4 ++-- src/cpsp/adminHederaAccount.cpsp | 1 - windows_parse_proto.sh | 19 +++++++++++++++++++ 10 files changed, 53 insertions(+), 16 deletions(-) rename compile_proto.sh => parse_proto.sh (100%) mode change 100755 => 100644 create mode 100644 windows_parse_proto.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a24af9a3..fc2eb1771 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ project(Gradido_LoginServer C CXX) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin" ) SET ( CMAKE_CXX_FLAGS "-std=c++17" ) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories( "dependencies" @@ -12,6 +14,7 @@ include_directories( "dependencies/mariadb-connector-c/build/include" "dependencies/spirit-po/include" "dependencies/grpc/include" + "dependencies/grpc/third_party/protobuf/src" "src/cpp/proto" #"dependencies/mariadb-connector-c/build/include" #"dependencies/mariadb-connector-c/include" @@ -99,6 +102,7 @@ set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/D set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") set(GRPC_RE2_PATH "dependencies/grpc/_build/third_party/re2/Debug") +set(GRPC_PROTOBUF_DEBUG_PATH "dependencies/grpc/_build/third_party/protobuf/Debug") find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) @@ -112,6 +116,9 @@ find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_RE2 re2 ${GRPC_RE2_PATH} REQUIRED) +find_library(PROTOBUF_LIB_DEBUG libprotobufd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) +find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) +find_library(PROTOBUF_LIBC_DEBUG libprotocd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) set(GRPC_LIBS @@ -123,6 +130,12 @@ set(GRPC_LIBS ${GRPC_BORING_SSL_SSL} ${GRPC_RE2} ) +set(PROTOBUF_DEBUG_LIBS + ${PROTOBUF_LIB_DEBUG} + ${PROTOBUF_LIB_LITE_DEBUG} + ${PROTOBUF_LIBC_DEBUG} +) + set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") @@ -174,7 +187,7 @@ target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::f if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS}) +TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) target_link_libraries(Gradido_LoginServer libmariadb protoc protobuf -pthread) endif(WIN32) diff --git a/README b/README index 89783a878..993dd4afa 100644 --- a/README +++ b/README @@ -25,6 +25,7 @@ mkdir _build cd _build cmake .. make +# under windows build at least release for protoc.exe and grpc c++ plugin cd ../../../ # get more dependencies with conan (need conan from https://conan.io/) diff --git a/conanfile.txt b/conanfile.txt index 96bd6f5c8..a6c09d9fa 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,7 +1,6 @@ [requires] Poco/1.9.4@pocoproject/stable libsodium/1.0.18@bincrafters/stable -protobuf/3.9.1@bincrafters/stable boost/1.71.0@conan/stable gtest/1.8.1@bincrafters/stable diff --git a/compile_proto.sh b/parse_proto.sh old mode 100755 new mode 100644 similarity index 100% rename from compile_proto.sh rename to parse_proto.sh diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index a9d4165c3..e98a02d92 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -264,16 +264,15 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request #line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
\n"; - responseStream << "\t\t\t\t\t
\n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t"; -#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; @@ -282,7 +281,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t\n"; @@ -296,21 +295,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
\n"; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 58c71b5ec..57cb14672 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -28,7 +28,6 @@ namespace controller { { auto db = new model::table::HederaAccount(); auto hedera_account_list = db->loadFromDB(fieldName, fieldValue, 2); - std::vector> resultVector; resultVector.reserve(hedera_account_list.size()); for (auto it = hedera_account_list.begin(); it != hedera_account_list.end(); it++) { diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index ec1c6c2a0..32c6772c6 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -1,6 +1,8 @@ #include "HederaRequest.h" #include "../proto/hedera/CryptoService.grpc.pb.h" +#include "../lib/DataTypeConverter.h" + #include #include #include @@ -22,16 +24,22 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query) auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); grpc::ClientContext context; std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + - std::chrono::milliseconds(100); + std::chrono::milliseconds(10000); context.set_deadline(deadline); + grpc::CompletionQueue cq; auto proto_query = query->getProtoQuery(); + auto proto_query_serialized = proto_query->SerializeAsString(); + auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); + printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); proto::Response* response = nullptr; if (proto_query->has_cryptogetaccountbalance()) { auto stub = proto::CryptoService::NewStub(channel); auto connect_string = query->getConnectionString(); printf("try connection to hedera with: %s\n", connect_string.data()); + //auto stream = stub->PrepareAsynccryptoGetBalance(&context, *proto_query, &cq); auto status = stub->cryptoGetBalance(&context, *proto_query, response); + //stream->StartCall(); addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); } diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index d47449bc6..39b3700c4 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -25,7 +25,7 @@ namespace model { auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance(); accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); - query_header->set_responsetype(proto::ANSWER_ONLY); + query_header->set_responsetype(proto::COST_ANSWER); auto transaction = query_header->mutable_payment(); //auto transaction_body = transaction->mutable_body(); // body content @@ -48,7 +48,7 @@ namespace model { auto account_amounts = transfer_list->mutable_accountamounts(); account_amounts->Add(); auto account_amount = account_amounts->Mutable(0); - account_amount->set_amount(0); + account_amount->set_amount(1000); connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); return query; diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index b4fd1f485..5379e4ef4 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -170,7 +170,6 @@
<%= hedera_account_model->getBalanceDouble() %> hbar
<%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
<%= hedera_account_model->getUpdatedString() %>
-
diff --git a/windows_parse_proto.sh b/windows_parse_proto.sh new file mode 100644 index 000000000..4c5d56d47 --- /dev/null +++ b/windows_parse_proto.sh @@ -0,0 +1,19 @@ +#!/bin/bash +if [ ! -d "./src/cpp/proto" ] ; then + mkdir ./src/cpp/proto +fi +if [ ! -d "./src/cpp/proto/gradido" ] ; then + mkdir ./src/cpp/proto/gradido +fi +PROTOC_PATH=./dependencies/grpc/_build/third_party/protobuf/Release +CPP_PLUGIN_PATH=./dependencies/grpc/_build/Release +$PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto + +if [ ! -d "./src/cpp/proto/hedera" ] ; then + mkdir ./src/cpp/proto/hedera +fi + +GOOGLE_PROTOBUF_INCLUDES=./dependencies/grpc/third_party/protobuf/src +$PROTOC_PATH/protoc --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto + + From 43f7038af723d0153066cc9d11c9dd14d079ab09 Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 3 Sep 2020 12:43:32 +0200 Subject: [PATCH 024/195] hedera query get balance now working =D --- .../HTTPInterface/AdminHederaAccountPage.cpp | 36 +++++--- src/cpp/HTTPInterface/ElopageWebhook.h | 4 +- .../PageRequestMessagedHandler.h | 4 +- src/cpp/JSONInterface/JsonRequestHandler.cpp | 2 +- src/cpp/JSONInterface/JsonRequestHandler.h | 4 +- src/cpp/SingletonManager/ConnectionManager.h | 4 +- src/cpp/SingletonManager/ErrorManager.cpp | 14 +-- src/cpp/SingletonManager/ErrorManager.h | 10 +- src/cpp/SingletonManager/SessionManager.cpp | 6 +- src/cpp/SingletonManager/SessionManager.h | 2 +- src/cpp/controller/HederaAccount.cpp | 24 ++++- src/cpp/controller/HederaAccount.h | 2 +- src/cpp/controller/HederaRequest.cpp | 62 ++++++++++--- src/cpp/controller/HederaRequest.h | 8 +- src/cpp/lib/DataTypeConverter.cpp | 9 +- src/cpp/lib/DataTypeConverter.h | 5 +- src/cpp/lib/Error.cpp | 10 +- src/cpp/lib/Error.h | 25 ++--- src/cpp/lib/JsonRequest.cpp | 91 ++++++++++++++++++- src/cpp/lib/JsonRequest.h | 6 +- src/cpp/lib/MultithreadContainer.cpp | 4 +- src/cpp/lib/Notification.cpp | 7 ++ src/cpp/lib/Notification.h | 24 +++++ .../{ErrorList.cpp => NotificationList.cpp} | 49 ++++++---- .../lib/{ErrorList.h => NotificationList.h} | 17 ++-- src/cpp/lib/Success.cpp | 52 +++++++++++ src/cpp/lib/Success.h | 30 ++++++ src/cpp/model/Session.h | 4 +- src/cpp/model/TransactionBase.h | 4 +- src/cpp/model/User.cpp | 4 +- src/cpp/model/User.h | 8 +- src/cpp/model/email/Email.h | 4 +- .../hedera/CryptoTransferTransaction.cpp | 53 +++++++++++ .../model/hedera/CryptoTransferTransaction.h | 40 ++++++++ src/cpp/model/hedera/Query.cpp | 80 ++++++++-------- src/cpp/model/hedera/Query.h | 6 +- src/cpp/model/hedera/Response.cpp | 32 +++++++ src/cpp/model/hedera/Response.h | 38 ++++++++ src/cpp/model/hedera/Transaction.cpp | 43 +++++++++ src/cpp/model/hedera/Transaction.h | 38 ++++++++ src/cpp/model/hedera/TransactionBody.cpp | 47 ++++++++++ src/cpp/model/hedera/TransactionBody.h | 39 ++++++++ src/cpp/model/table/ModelBase.h | 2 +- src/cpp/tasks/ProcessingTransaction.h | 4 +- src/cpp/tasks/SigningTransaction.h | 4 +- src/cpp/tasks/Task.cpp | 4 +- src/cpsp/adminHederaAccount.cpsp | 7 ++ 47 files changed, 796 insertions(+), 176 deletions(-) create mode 100644 src/cpp/lib/Notification.cpp create mode 100644 src/cpp/lib/Notification.h rename src/cpp/lib/{ErrorList.cpp => NotificationList.cpp} (75%) rename src/cpp/lib/{ErrorList.h => NotificationList.h} (76%) create mode 100644 src/cpp/lib/Success.cpp create mode 100644 src/cpp/lib/Success.h create mode 100644 src/cpp/model/hedera/CryptoTransferTransaction.cpp create mode 100644 src/cpp/model/hedera/CryptoTransferTransaction.h diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index e98a02d92..fa99a7b35 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -12,6 +12,8 @@ #include "../controller/HederaId.h" #include "../controller/CryptoKey.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/Success.h" #include "../SingletonManager/SessionManager.h" #include "../ServerConfig.h" @@ -37,12 +39,14 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 20 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 22 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Profiler hedera_time; + std::string hedera_time_string; Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); @@ -65,7 +69,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { + hedera_time.reset(); hedera_account[0]->updateBalanceFromHedera(user, this); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } } @@ -225,7 +231,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 150 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; @@ -242,37 +248,37 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
Aktionen
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t"; -#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t
"; -#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
\n"; responseStream << "\t\t\t\t\t
"; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t"; -#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; @@ -281,7 +287,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t\n"; @@ -295,21 +301,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
\n"; diff --git a/src/cpp/HTTPInterface/ElopageWebhook.h b/src/cpp/HTTPInterface/ElopageWebhook.h index bf8ea4efc..77c60b155 100644 --- a/src/cpp/HTTPInterface/ElopageWebhook.h +++ b/src/cpp/HTTPInterface/ElopageWebhook.h @@ -4,7 +4,7 @@ #include "PageRequestMessagedHandler.h" #include "../tasks/CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "Poco/Net/NameValueCollection.h" @@ -14,7 +14,7 @@ public: void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); }; -class HandleElopageRequestTask : public UniLib::controller::CPUTask, protected ErrorList +class HandleElopageRequestTask : public UniLib::controller::CPUTask, protected NotificationList { public: HandleElopageRequestTask(Poco::Net::NameValueCollection& requestData); diff --git a/src/cpp/HTTPInterface/PageRequestMessagedHandler.h b/src/cpp/HTTPInterface/PageRequestMessagedHandler.h index 2e47b398d..396fc8a4e 100644 --- a/src/cpp/HTTPInterface/PageRequestMessagedHandler.h +++ b/src/cpp/HTTPInterface/PageRequestMessagedHandler.h @@ -2,7 +2,7 @@ #define PAGE_REQUEST_MESSAGE_HANDLER_INCLUDED #include "../model/Session.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/Profiler.h" #include "../SingletonManager/LanguageManager.h" @@ -11,7 +11,7 @@ #include "Poco/Net/HTMLForm.h" #include "Poco/RegularExpression.h" -class PageRequestMessagedHandler : public Poco::Net::HTTPRequestHandler, public ErrorList +class PageRequestMessagedHandler : public Poco::Net::HTTPRequestHandler, public NotificationList { public: PageRequestMessagedHandler() {} diff --git a/src/cpp/JSONInterface/JsonRequestHandler.cpp b/src/cpp/JSONInterface/JsonRequestHandler.cpp index 123c36268..47abb959a 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandler.cpp @@ -48,7 +48,7 @@ void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Po } -Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& request_stream, ErrorList* errorHandler /* = nullptr*/, const char* functionName /* = nullptr*/) +Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& request_stream, NotificationList* errorHandler /* = nullptr*/, const char* functionName /* = nullptr*/) { // debugging answer diff --git a/src/cpp/JSONInterface/JsonRequestHandler.h b/src/cpp/JSONInterface/JsonRequestHandler.h index 72230bfe4..90c3e3171 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.h +++ b/src/cpp/JSONInterface/JsonRequestHandler.h @@ -4,7 +4,7 @@ #include "Poco/Net/HTTPRequestHandler.h" #include "Poco/JSON/Object.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" class JsonRequestHandler : public Poco::Net::HTTPRequestHandler @@ -15,7 +15,7 @@ public: virtual Poco::JSON::Object* handle(Poco::Dynamic::Var params) = 0; - static Poco::Dynamic::Var parseJsonWithErrorPrintFile(std::istream& request_stream, ErrorList* errorHandler = nullptr, const char* functionName = nullptr); + static Poco::Dynamic::Var parseJsonWithErrorPrintFile(std::istream& request_stream, NotificationList* errorHandler = nullptr, const char* functionName = nullptr); protected: Poco::JSON::Object* mResultJson; diff --git a/src/cpp/SingletonManager/ConnectionManager.h b/src/cpp/SingletonManager/ConnectionManager.h index 795808515..0dfd8b54c 100644 --- a/src/cpp/SingletonManager/ConnectionManager.h +++ b/src/cpp/SingletonManager/ConnectionManager.h @@ -9,7 +9,7 @@ #include "../MySQL/Poco/Connector.h" #include "Poco/Exception.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" enum ConnectionType { CONNECTION_MYSQL_LOGIN_SERVER, @@ -17,7 +17,7 @@ enum ConnectionType { CONNECTION_MAX }; -class ConnectionManager : public ErrorList +class ConnectionManager : public NotificationList { public: ~ConnectionManager(); diff --git a/src/cpp/SingletonManager/ErrorManager.cpp b/src/cpp/SingletonManager/ErrorManager.cpp index 090a6f9dd..b4df67974 100644 --- a/src/cpp/SingletonManager/ErrorManager.cpp +++ b/src/cpp/SingletonManager/ErrorManager.cpp @@ -4,7 +4,7 @@ #include "Poco/Net/SecureSMTPClientSession.h" #include "Poco/Net/StringPartSource.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../model/email/Email.h" @@ -34,19 +34,19 @@ ErrorManager::~ErrorManager() mErrorsMap.clear(); } -void ErrorManager::addError(Error* error, bool log/* = true*/) +void ErrorManager::addError(Notification* error, bool log/* = true*/) { DHASH id = DRMakeStringHash(error->getFunctionName()); mWorkingMutex.lock(); auto it = mErrorsMap.find(id); - std::list* list = nullptr; + std::list* list = nullptr; //printf("[ErrorManager::addError] error with function: %s, %s\n", error->getFunctionName(), error->getMessage()); if(log) mLogging.error("[ErrorManager::addError] %s", error->getString(false)); if (it == mErrorsMap.end()) { - list = new std::list; - mErrorsMap.insert(std::pair*>(id, list)); + list = new std::list; + mErrorsMap.insert(std::pair*>(id, list)); } else { list = it->second; @@ -62,9 +62,9 @@ void ErrorManager::addError(Error* error, bool log/* = true*/) } -int ErrorManager::getErrors(ErrorList* send) +int ErrorManager::getErrors(NotificationList* send) { - Error* error = nullptr; + Notification* error = nullptr; int iCount = 0; while (error = send->getLastError()) { addError(error, false); diff --git a/src/cpp/SingletonManager/ErrorManager.h b/src/cpp/SingletonManager/ErrorManager.h index e59bd7d35..a0e427d9e 100644 --- a/src/cpp/SingletonManager/ErrorManager.h +++ b/src/cpp/SingletonManager/ErrorManager.h @@ -15,7 +15,7 @@ #include #include #include -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/DRHash.h" #include "../tasks/CPUTask.h" @@ -24,7 +24,7 @@ #include "Poco/Net/MailMessage.h" -class ErrorManager : public IErrorCollection +class ErrorManager : public INotificationCollection { public: ~ErrorManager(); @@ -32,9 +32,9 @@ public: static ErrorManager* getInstance(); // will called delete on error - virtual void addError(Error* error, bool log = true); + virtual void addError(Notification* error, bool log = true); - int getErrors(ErrorList* send); + int getErrors(NotificationList* send); virtual void sendErrorsAsEmail(); @@ -43,7 +43,7 @@ protected: // access mutex Poco::Mutex mWorkingMutex; - std::map*> mErrorsMap; + std::map*> mErrorsMap; // how many errors should be stored // poco logging diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index f8dbb318f..bbeaf9052 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -170,7 +170,7 @@ Session* SessionManager::getNewSession(int* handle) } } else { - ErrorList errors; + NotificationList errors; errors.addError(new Error(functionName, "found dead locked session, keeping in memory without reference")); errors.addError(new ParamError(functionName, "last succeeded lock:", result->getLastSucceededLock().data())); errors.sendErrorsAsEmail(); @@ -235,7 +235,7 @@ bool SessionManager::releaseSession(int requestHandleSession) session->setActive(false); } else { - ErrorList errors; + NotificationList errors; errors.addError(new Error("SessionManager::releaseSession", "found dead locked session")); errors.sendErrorsAsEmail(); mRequestSessionMap.erase(requestHandleSession); @@ -531,7 +531,7 @@ void SessionManager::deleteLoginCookies(Poco::Net::HTTPServerRequest& request, P //session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); } -bool SessionManager::checkPwdValidation(const std::string& pwd, ErrorList* errorReciver) +bool SessionManager::checkPwdValidation(const std::string& pwd, NotificationList* errorReciver) { if (!isValid(pwd, VALIDATE_PASSWORD)) { errorReciver->addError(new Error("Passwort", "Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-_) ein!")); diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index 5968e3a25..99ef301f0 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -69,7 +69,7 @@ public: bool isValid(const std::string& subject, SessionValidationTypes validationType); //! \return true if password is valid - bool checkPwdValidation(const std::string& pwd, ErrorList* errorReciver); + bool checkPwdValidation(const std::string& pwd, NotificationList* errorReciver); void checkTimeoutSession(); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 57cb14672..6fabe2848 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver/* = nullptr*/) + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -86,27 +86,45 @@ namespace controller { auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); if (crypto_key.isNull()) { - printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); + if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));} + else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); } return false; } auto hedera_key_pair = crypto_key->getKeyPair(user); if (!hedera_key_pair) { + if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));} printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); return false; } + auto query = model::hedera::Query::getBalance(mHederaID, hedera_node); + if (!query) { printf("[%s] error creating query\n", functionName); } query->sign(std::move(hedera_key_pair)); HederaRequest request; + model::hedera::Response response; try { - request.request(query); + if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response) && proto::OK == response.getResponseCode()) { + account_model->updateIntoDB("balance", response.getAccountBalance()); + } + else { + if (errorReceiver) { + errorReceiver->addError(new Error("Hedera", "Hedera request failed")); + errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); + } + else { + printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data()); + } + } + //request.requestViaPHPRelay(query); } catch (Poco::Exception& ex) { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } + if (errorReceiver) { errorReceiver->getErrors(&request); } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 7f08adddc..d76420b78 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -27,7 +27,7 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver = nullptr); + bool updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 32c6772c6..308ffa5e8 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -9,6 +9,7 @@ #include #include + HederaRequest::HederaRequest() { @@ -19,29 +20,62 @@ HederaRequest::~HederaRequest() } -HederaRequestReturn HederaRequest::request(model::hedera::Query* query) +HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee/* = 0*/) { auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); + grpc::ClientContext context; std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + - std::chrono::milliseconds(10000); + std::chrono::milliseconds(5000); context.set_deadline(deadline); - grpc::CompletionQueue cq; + //grpc::CompletionQueue cq; auto proto_query = query->getProtoQuery(); + auto proto_query_serialized = proto_query->SerializeAsString(); - auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); - printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); - proto::Response* response = nullptr; + //auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); + //printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); + + auto proto_response = response->getResponsePtr(); + auto connect_string = query->getConnectionString(); + if (proto_query->has_cryptogetaccountbalance()) { - auto stub = proto::CryptoService::NewStub(channel); - auto connect_string = query->getConnectionString(); - printf("try connection to hedera with: %s\n", connect_string.data()); - //auto stream = stub->PrepareAsynccryptoGetBalance(&context, *proto_query, &cq); - auto status = stub->cryptoGetBalance(&context, *proto_query, response); - //stream->StartCall(); - addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); - printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); + auto stub = proto::CryptoService::NewStub(channel); + // crypto account get balance currently hasn't fees + query->setResponseType(proto::ANSWER_ONLY); + + auto status = stub->cryptoGetBalance(&context, *proto_query, proto_response); + if (status.ok()) { + return HEDERA_REQUEST_RETURN_OK; + } + else { + addError(new ParamError("Hedera Request", "crypto get balance error message:", status.error_message())); + addError(new ParamError("Hedera Request", "details: ", status.error_details())); + return HEDERA_REQUEST_RETURN_ERROR; + } + + } return HEDERA_REQUEST_RETURN_OK; +} + +#include "Poco/JSON/Object.h" +#include "../lib/JsonRequest.h" + +HederaRequestReturn HederaRequest::requestViaPHPRelay(model::hedera::Query* query) +{ + JsonRequest phpRelay("***REMOVED***", 88); + Poco::Net::NameValueCollection parameters; + std::string query_string = query->getProtoQuery()->SerializeAsString(); + //auto query_base64 = DataTypeConverter::binToBase64((const unsigned char*)query_string.data(), query_string.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); + //auto findPos = query_string.find_first_of("\u"); + auto query_hex = DataTypeConverter::binToHex((const unsigned char*)query_string.data(), query_string.size()); + parameters.set("content", query_hex.substr(0, query_hex.size()-1)); + parameters.set("server", query->getConnectionString()); + parameters.set("method", "getBalance"); + parameters.set("service", "crypto"); + phpRelay.requestGRPCRelay(parameters); + //phpRelay.request("") + + return HEDERA_REQUEST_RETURN_OK; } \ No newline at end of file diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 692215f8d..327ee7634 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -12,6 +12,8 @@ #include "../controller/NodeServer.h" #include "../model/hedera/Query.h" +#include "../model/hedera/Transaction.h" +#include "../model/hedera/Response.h" enum HederaRequestReturn { @@ -22,13 +24,15 @@ enum HederaRequestReturn }; // NodeServerConnection -class HederaRequest : public ErrorList +class HederaRequest : public NotificationList { public: HederaRequest(); ~HederaRequest(); - HederaRequestReturn request(model::hedera::Query* query); + HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); + //! for testing, didn't work server say invalid json :/ + HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); protected: diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index a97cb8d0e..72e6aceb8 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -138,18 +138,17 @@ namespace DataTypeConverter } - std::string binToBase64(const MemoryBin* data) + std::string binToBase64(const unsigned char* data, size_t size, int variant /*= sodium_base64_VARIANT_ORIGINAL*/) { auto mm = MemoryManager::getInstance(); - size_t binSize = data->size(); - size_t encodedSize = sodium_base64_encoded_len(binSize, sodium_base64_VARIANT_ORIGINAL); - + + size_t encodedSize = sodium_base64_encoded_len(size, variant); auto base64 = mm->getFreeMemory(encodedSize); memset(*base64, 0, encodedSize); size_t resultBinSize = 0; - if (0 != sodium_bin2base64(*base64, encodedSize, *data, binSize, sodium_base64_VARIANT_ORIGINAL)) { + if (nullptr == sodium_bin2base64(*base64, encodedSize, data, size, variant)) { mm->releaseMemory(base64); return ""; } diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index 0dad46954..d970d697d 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -9,6 +9,8 @@ #include "Poco/Data/LOB.h" #include "../SingletonManager/LanguageManager.h" +#include "sodium.h" + namespace DataTypeConverter { enum NumberParseState @@ -25,8 +27,9 @@ namespace DataTypeConverter { MemoryBin* hexToBin(const std::string& hexString); MemoryBin* base64ToBin(const std::string& base64String); - std::string binToBase64(const MemoryBin* data); + std::string binToBase64(const unsigned char* data, size_t size, int variant = sodium_base64_VARIANT_ORIGINAL); + inline std::string binToBase64(const MemoryBin* data, int variant = sodium_base64_VARIANT_ORIGINAL) { return binToBase64(data->data(), data->size(), variant); } std::string binToHex(const unsigned char* data, size_t size); std::string binToHex(const Poco::Nullable& nullableBin); diff --git a/src/cpp/lib/Error.cpp b/src/cpp/lib/Error.cpp index c44f48711..9897d7930 100644 --- a/src/cpp/lib/Error.cpp +++ b/src/cpp/lib/Error.cpp @@ -2,7 +2,7 @@ Error::Error(const char* functionName, const char* message) - : mFunctionName(functionName), mMessage(message) + : Notification(functionName, message) { } @@ -12,7 +12,7 @@ Error::~Error() } -std::string Error::getString(bool withNewline/* = true*/) +std::string Error::getString(bool withNewline/* = true*/) const { std::stringstream ss; ss << mFunctionName << ": " << mMessage; @@ -20,7 +20,7 @@ std::string Error::getString(bool withNewline/* = true*/) return ss.str(); } -std::string Error::getHtmlString() +std::string Error::getHtmlString() const { std::stringstream ss; ss << mFunctionName << ": " << mMessage; @@ -28,7 +28,7 @@ std::string Error::getHtmlString() return ss.str(); } -std::string ParamError::getString(bool withNewline/* = true*/) +std::string ParamError::getString(bool withNewline/* = true*/) const { std::stringstream ss; ss << mFunctionName << ": " << mMessage << " " << mParam; @@ -36,7 +36,7 @@ std::string ParamError::getString(bool withNewline/* = true*/) return ss.str(); } -std::string ParamError::getHtmlString() +std::string ParamError::getHtmlString() const { std::stringstream ss; ss << mFunctionName << ": " << mMessage << " " << mParam << std::endl; diff --git a/src/cpp/lib/Error.h b/src/cpp/lib/Error.h index e85b01455..444a2ddc0 100644 --- a/src/cpp/lib/Error.h +++ b/src/cpp/lib/Error.h @@ -10,23 +10,24 @@ #ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_H #define DR_LUA_WEB_MODULE_ERROR_ERROR_H -#include +#include "Notification.h" + #include -class Error + +class Error : public Notification { public: Error(const char* functionName, const char* message); ~Error(); - const char* getFunctionName() { return mFunctionName.data(); } - const char* getMessage() { return mMessage.data(); } - virtual std::string getString(bool withNewline = true); - virtual std::string getHtmlString(); + virtual std::string getString(bool withNewline = true) const; + virtual std::string getHtmlString() const; + + virtual bool isError() { return true; } protected: - std::string mFunctionName; - std::string mMessage; + }; class ParamError : public Error @@ -44,18 +45,18 @@ public: mParam = ss.str(); } - virtual std::string getString(bool withNewline = true); - virtual std::string getHtmlString(); + virtual std::string getString(bool withNewline = true) const; + virtual std::string getHtmlString() const; protected: std::string mParam; }; -class IErrorCollection +class INotificationCollection { public: - virtual void addError(Error*, bool log = true) = 0; + virtual void addError(Notification*, bool log = true) = 0; }; #endif // DR_LUA_WEB_MODULE_ERROR_ERROR_H diff --git a/src/cpp/lib/JsonRequest.cpp b/src/cpp/lib/JsonRequest.cpp index 5e5bedb47..da8bb19bb 100644 --- a/src/cpp/lib/JsonRequest.cpp +++ b/src/cpp/lib/JsonRequest.cpp @@ -37,7 +37,6 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::Net:: try { Profiler phpRequestTime; Poco::Net::HTTPSClientSession httpsClientSession(mServerHost, mServerPort); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); request.setChunkedTransferEncoding(true); @@ -99,5 +98,95 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::Net:: return JSON_REQUEST_CONNECT_ERROR; } + return JSON_REQUEST_RETURN_OK; +} +#include "Poco/JSON/Stringifier.h" +JsonRequestReturn JsonRequest::requestGRPCRelay(const Poco::Net::NameValueCollection& payload) +{ + static const char* functionName = "JsonRequest::requestGRPCRelay"; + Poco::JSON::Object requestJson; + + for (auto it = payload.begin(); it != payload.end(); it++) { + requestJson.set(it->first, it->second); + } + + // send post request via https + // 443 = HTTPS Default + // TODO: adding port into ServerConfig + try { + Profiler phpRequestTime; + Poco::Net::HTTPClientSession httpClientSession(mServerHost, mServerPort); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/hedera_rpc_relay/gRPCProxy.php"); + + request.setChunkedTransferEncoding(false); + std::ostream& requestStream = httpClientSession.sendRequest(request); + requestJson.stringify(requestStream); + + std::stringstream ss; + requestJson.stringify(ss); + auto f = fopen("grpc.txt", "wt"); + std::string grpc = ss.str(); + fwrite(grpc.data(), grpc.size(), 1, f); + fclose(f); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = httpClientSession.receiveResponse(response); + + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + Poco::Logger& speedLog = Poco::Logger::get("SpeedLog"); + speedLog.information("[gRPC relay] php server time: %s", phpRequestTime.string()); + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + } + catch (Poco::Exception& ex) { + addError(new ParamError(functionName, "error parsing request answer grpc relay", ex.displayText().data())); + + std::string fileName = "response_grpc_"; + fileName += ".html"; + + FILE* f = fopen(fileName.data(), "wt"); + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + // */ + sendErrorsAsEmail(responseStringStream.str()); + return JSON_REQUEST_RETURN_PARSE_ERROR; + } + + Poco::JSON::Object object = *parsedJson.extract(); + auto state = object.get("state"); + std::string stateString = state.convert(); + if (stateString == "error") { + addError(new Error(functionName, "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError(functionName, "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError(functionName, "details:", object.get("details").convert().data())); + } + sendErrorsAsEmail(); + return JSON_REQUEST_RETURN_ERROR; + } + ss.clear(); + Poco::JSON::Stringifier::stringify(object, ss); + printf("json request result: %s\n", ss.str().data()); + } + catch (Poco::Exception& e) { + addError(new ParamError(functionName, "connect error to php server", e.displayText().data())); + sendErrorsAsEmail(); + return JSON_REQUEST_CONNECT_ERROR; + } + + + return JSON_REQUEST_RETURN_OK; } \ No newline at end of file diff --git a/src/cpp/lib/JsonRequest.h b/src/cpp/lib/JsonRequest.h index 87350c002..e13046594 100644 --- a/src/cpp/lib/JsonRequest.h +++ b/src/cpp/lib/JsonRequest.h @@ -8,7 +8,7 @@ * */ -#include "ErrorList.h" +#include "NotificationList.h" #include "Poco/Net/NameValueCollection.h" #ifndef __GRADIDO_LOGIN_SERVER_LIB_JSON_REQUEST_ @@ -22,17 +22,19 @@ enum JsonRequestReturn JSON_REQUEST_CONNECT_ERROR }; -class JsonRequest : public ErrorList +class JsonRequest : public NotificationList { public: JsonRequest(const std::string& serverHost, int serverPort); ~JsonRequest(); JsonRequestReturn request(const char* methodName, const Poco::Net::NameValueCollection& payload); + JsonRequestReturn requestGRPCRelay(const Poco::Net::NameValueCollection& payload); protected: int mServerPort; std::string mServerHost; + }; diff --git a/src/cpp/lib/MultithreadContainer.cpp b/src/cpp/lib/MultithreadContainer.cpp index fc72593a1..d73a6a882 100644 --- a/src/cpp/lib/MultithreadContainer.cpp +++ b/src/cpp/lib/MultithreadContainer.cpp @@ -1,5 +1,5 @@ #include "MultithreadContainer.h" -#include "ErrorList.h" +#include "NotificationList.h" namespace UniLib { namespace lib { @@ -14,7 +14,7 @@ namespace UniLib { } } catch (Poco::TimeoutException& ex) { - ErrorList errors; + NotificationList errors; errors.addError(new ParamError(functionName, "lock timeout", ex.displayText())); if (mLastSucceededLock != "") { errors.addError(new ParamError(functionName, "last succeed lock by ", mLastSucceededLock.data())); diff --git a/src/cpp/lib/Notification.cpp b/src/cpp/lib/Notification.cpp new file mode 100644 index 000000000..15d622923 --- /dev/null +++ b/src/cpp/lib/Notification.cpp @@ -0,0 +1,7 @@ +#include "Notification.h" + +Notification::Notification(const char* functionName, const char* message) + : mFunctionName(functionName), mMessage(message) +{ + +} \ No newline at end of file diff --git a/src/cpp/lib/Notification.h b/src/cpp/lib/Notification.h new file mode 100644 index 000000000..419b861bc --- /dev/null +++ b/src/cpp/lib/Notification.h @@ -0,0 +1,24 @@ +#ifndef GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H +#define GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H + +#include + +class Notification +{ +public: + Notification(const char* functionName, const char* message); + + const char* getFunctionName() { return mFunctionName.data(); } + const char* getMessage() { return mMessage.data(); } + virtual std::string getString(bool withNewline = true) const = 0; + virtual std::string getHtmlString() const = 0; + + virtual bool isError() { return false; } + virtual bool isSuccess() { return false; } + +protected: + std::string mFunctionName; + std::string mMessage; +}; + +#endif //GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H \ No newline at end of file diff --git a/src/cpp/lib/ErrorList.cpp b/src/cpp/lib/NotificationList.cpp similarity index 75% rename from src/cpp/lib/ErrorList.cpp rename to src/cpp/lib/NotificationList.cpp index 0a03afb01..48e96b685 100644 --- a/src/cpp/lib/ErrorList.cpp +++ b/src/cpp/lib/NotificationList.cpp @@ -1,4 +1,4 @@ -#include "ErrorList.h" +#include "NotificationList.h" #include "../ServerConfig.h" @@ -42,13 +42,13 @@ int SendErrorMessage::run() // ------------------------------------------------------------------------------------ -ErrorList::ErrorList() +NotificationList::NotificationList() : mLogging(Poco::Logger::get("errorLog")) { } -ErrorList::~ErrorList() +NotificationList::~NotificationList() { while (mErrorStack.size() > 0) { delete mErrorStack.top(); @@ -56,7 +56,7 @@ ErrorList::~ErrorList() } } -void ErrorList::addError(Error* error, bool log/* = true */) +void NotificationList::addError(Notification* error, bool log/* = true */) { if (log) { @@ -67,13 +67,18 @@ void ErrorList::addError(Error* error, bool log/* = true */) mErrorStack.push(error); } -Error* ErrorList::getLastError() +void NotificationList::addNotification(Notification* notification) +{ + mErrorStack.push(notification); +} + +Notification* NotificationList::getLastError() { if (mErrorStack.size() == 0) { return nullptr; } - Error* error = mErrorStack.top(); + Notification* error = mErrorStack.top(); if (error) { mErrorStack.pop(); } @@ -81,7 +86,7 @@ Error* ErrorList::getLastError() return error; } -void ErrorList::clearErrors() +void NotificationList::clearErrors() { while (mErrorStack.size()) { auto error = mErrorStack.top(); @@ -93,9 +98,9 @@ void ErrorList::clearErrors() } -int ErrorList::getErrors(ErrorList* send) +int NotificationList::getErrors(NotificationList* send) { - Error* error = nullptr; + Notification* error = nullptr; int iCount = 0; while (error = send->getLastError()) { addError(error, false); @@ -104,7 +109,7 @@ int ErrorList::getErrors(ErrorList* send) return iCount; } -void ErrorList::printErrors() +void NotificationList::printErrors() { while (mErrorStack.size() > 0) { auto error = mErrorStack.top(); @@ -114,14 +119,19 @@ void ErrorList::printErrors() } } -std::string ErrorList::getErrorsHtml() +std::string NotificationList::getErrorsHtml() { std::string res; res = "
    "; while (mErrorStack.size() > 0) { auto error = mErrorStack.top(); mErrorStack.pop(); - res += "
  • "; + if (error->isError()) { + res += "
  • "; + } + else if (error->isSuccess()) { + res += "
  • "; + } res += error->getHtmlString(); res += "
  • "; delete error; @@ -130,15 +140,20 @@ std::string ErrorList::getErrorsHtml() return res; } -std::string ErrorList::getErrorsHtmlNewFormat() +std::string NotificationList::getErrorsHtmlNewFormat() { std::string html; while (mErrorStack.size() > 0) { - auto error = std::unique_ptr(mErrorStack.top()); + auto error = std::unique_ptr(mErrorStack.top()); mErrorStack.pop(); - html += "
    "; - html += "report_problem"; + if (error->isError()) { + html += "
    "; + html += "report_problem"; + } + else if (error->isSuccess()) { + html += "
    "; + } html += ""; html += error->getHtmlString(); html += ""; @@ -154,7 +169,7 @@ std::string ErrorList::getErrorsHtmlNewFormat() */ -void ErrorList::sendErrorsAsEmail(std::string rawHtml/* = ""*/) +void NotificationList::sendErrorsAsEmail(std::string rawHtml/* = ""*/) { auto em = EmailManager::getInstance(); /*auto message = new Poco::Net::MailMessage(); diff --git a/src/cpp/lib/ErrorList.h b/src/cpp/lib/NotificationList.h similarity index 76% rename from src/cpp/lib/ErrorList.h rename to src/cpp/lib/NotificationList.h index 3940a23c7..a3b2edcf1 100644 --- a/src/cpp/lib/ErrorList.h +++ b/src/cpp/lib/NotificationList.h @@ -19,27 +19,28 @@ #include "Poco/Net/StringPartSource.h" #include "Poco/Logger.h" -class ErrorList : public IErrorCollection +class NotificationList : public INotificationCollection { public: - ErrorList(); - ~ErrorList(); + NotificationList(); + ~NotificationList(); // push error, error will be deleted in deconstructor - virtual void addError(Error* error, bool log = true); + virtual void addError(Notification* error, bool log = true); + void addNotification(Notification* notification); // return error on top of stack, please delete after using - Error* getLastError(); + Notification* getLastError(); inline size_t errorCount() { return mErrorStack.size(); } // delete all errors void clearErrors(); - static int moveErrors(ErrorList* recv, ErrorList* send) { + static int moveErrors(NotificationList* recv, NotificationList* send) { return recv->getErrors(send); } - int getErrors(ErrorList* send); + int getErrors(NotificationList* send); void printErrors(); std::string getErrorsHtml(); @@ -48,7 +49,7 @@ public: void sendErrorsAsEmail(std::string rawHtml = ""); protected: - std::stack mErrorStack; + std::stack mErrorStack; // poco logging Poco::Logger& mLogging; }; diff --git a/src/cpp/lib/Success.cpp b/src/cpp/lib/Success.cpp new file mode 100644 index 000000000..5cf23f3b8 --- /dev/null +++ b/src/cpp/lib/Success.cpp @@ -0,0 +1,52 @@ +#include "Success.h" +#include + +Success::Success(const char* functionName, const char* message) + : Notification(functionName, message) +{ + +} + +std::string Success::getString(bool withNewline/* = true*/) const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage; + if (withNewline) ss << std::endl; + + return ss.str(); +} +std::string Success::getHtmlString() const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage; + + return ss.str(); +} + +ParamSuccess::ParamSuccess(const char* functionName, const char* message, std::string param) + : Success(functionName, message), mParam(param) +{ + +} + +ParamSuccess::ParamSuccess(const char* functionName, const char* message, int param) + : Success(functionName, message), mParam(std::to_string(param)) +{ + +} + +std::string ParamSuccess::getString(bool withNewline/* = true*/) const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage << " " << mParam; + if (withNewline) ss << std::endl; + + return ss.str(); +} +std::string ParamSuccess::getHtmlString() const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage << " " << mParam; + + return ss.str(); +} \ No newline at end of file diff --git a/src/cpp/lib/Success.h b/src/cpp/lib/Success.h new file mode 100644 index 000000000..4fc4b4fcf --- /dev/null +++ b/src/cpp/lib/Success.h @@ -0,0 +1,30 @@ +#ifndef GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H +#define GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H + +#include "Notification.h" + +class Success : public Notification +{ +public: + Success(const char* functionName, const char* message); + + std::string getString(bool withNewline = true) const; + std::string getHtmlString() const; + + virtual bool isSuccess() { return true; } +}; + +class ParamSuccess : public Success +{ +public: + ParamSuccess(const char* functionName, const char* message, std::string param); + ParamSuccess(const char* functionName, const char* message, int param); + + std::string getString(bool withNewline = true) const; + std::string getHtmlString() const; + +protected: + std::string mParam; +}; + +#endif //GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H \ No newline at end of file diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index 69a9612e0..6557ef30e 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -10,7 +10,7 @@ #ifndef DR_LUA_WEB_MODULE_SESSION_SESSION_H #define DR_LUA_WEB_MODULE_SESSION_SESSION_H -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "User.h" #include "../controller/User.h" @@ -54,7 +54,7 @@ class UpdateUserPasswordPage; class PassphrasePage; class RepairDefectPassphrase; -class Session : public ErrorList, public UniLib::lib::MultithreadContainer +class Session : public NotificationList, public UniLib::lib::MultithreadContainer { friend WriteEmailVerification; friend SessionManager; diff --git a/src/cpp/model/TransactionBase.h b/src/cpp/model/TransactionBase.h index 84406fddb..5bb0bad14 100644 --- a/src/cpp/model/TransactionBase.h +++ b/src/cpp/model/TransactionBase.h @@ -11,11 +11,11 @@ #pragma warning(disable:4800) -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../proto/gradido/BasicTypes.pb.h" #include "../SingletonManager/MemoryManager.h" -class TransactionBase : public ErrorList, public UniLib::lib::MultithreadContainer +class TransactionBase : public NotificationList, public UniLib::lib::MultithreadContainer { public: TransactionBase(const std::string& memo); diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index 80763d337..a57324cf8 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -732,7 +732,7 @@ void User::setEmailChecked() unlock(); } -bool User::validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint) +bool User::validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint) { auto mm = MemoryManager::getInstance(); auto cmpCryptoKey = createCryptoKey(pwd); @@ -935,7 +935,7 @@ MemoryBin* User::createCryptoKey(const std::string& password) return key; } -User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver/* = nullptr*/) +User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver/* = nullptr*/) { if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); diff --git a/src/cpp/model/User.h b/src/cpp/model/User.h index c041cea7d..cc1a8be86 100644 --- a/src/cpp/model/User.h +++ b/src/cpp/model/User.h @@ -4,7 +4,7 @@ #include "../Crypto/KeyPair.h" #include //#include "ModelBase.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "Poco/Thread.h" #include "Poco/Types.h" @@ -50,7 +50,7 @@ enum UserFields USER_FIELDS_LANGUAGE }; -class User : public ErrorList +class User : public NotificationList { friend UserCreateCryptoKey; friend UserWriteIntoDB; @@ -115,7 +115,7 @@ public: bool isEmptyPassword(); //bool setNewPassword(const std::string& newPassword); bool updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser); - bool validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint); + bool validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint); bool validateIdentHash(HASH hash); MemoryBin* encrypt(const MemoryBin* data); @@ -134,7 +134,7 @@ protected: typedef Poco::UInt64 passwordHashed; MemoryBin* createCryptoKey(const std::string& password); - static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver = nullptr); + static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver = nullptr); inline void setCryptoKey(MemoryBin* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); } //void detectState(); diff --git a/src/cpp/model/email/Email.h b/src/cpp/model/email/Email.h index d2887a26c..0fc52cac0 100644 --- a/src/cpp/model/email/Email.h +++ b/src/cpp/model/email/Email.h @@ -17,7 +17,7 @@ #include "../../SingletonManager/LanguageManager.h" -#include "../../lib/ErrorList.h" +#include "../../lib/NotificationList.h" namespace model { using namespace Poco; @@ -39,7 +39,7 @@ namespace model { EMAIL_MAX }; - class Email: public ErrorList + class Email: public NotificationList { public: Email(AutoPtr emailVerification, AutoPtr user, EmailType type); diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.cpp b/src/cpp/model/hedera/CryptoTransferTransaction.cpp new file mode 100644 index 000000000..828a85645 --- /dev/null +++ b/src/cpp/model/hedera/CryptoTransferTransaction.cpp @@ -0,0 +1,53 @@ +#include "CryptoTransferTransaction.h" + +namespace model { + namespace hedera { + + CryptoTransferTransaction::CryptoTransferTransaction() + : mCryptoTransfer(nullptr) + { + mCryptoTransfer = new proto::CryptoTransferTransactionBody; + } + + CryptoTransferTransaction::~CryptoTransferTransaction() + { + if (mCryptoTransfer) { + delete mCryptoTransfer; + mCryptoTransfer = nullptr; + } + } + + void CryptoTransferTransaction::addSender(Poco::AutoPtr senderAccountId, Poco::UInt64 amountTinybars) + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto accountAmounts = transfers->add_accountamounts(); + accountAmounts->set_amount(-(Poco::Int64)amountTinybars); + senderAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid()); + } + void CryptoTransferTransaction::addReceiver(Poco::AutoPtr receiverAccountId, Poco::UInt64 amountTinybars) + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto accountAmounts = transfers->add_accountamounts(); + accountAmounts->set_amount(amountTinybars); + receiverAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid()); + } + + bool CryptoTransferTransaction::validate() + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto account_amounts = transfers->accountamounts(); + Poco::Int64 sum = 0; + for (int i = 0; i < transfers->accountamounts_size(); i++) { + auto account_amount = account_amounts.Mutable(i); + sum += account_amount->amount(); + } + return 0 == sum && transfers->accountamounts_size() > 0; + } + + void CryptoTransferTransaction::resetPointer() + { + mCryptoTransfer = nullptr; + } + } +} + diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.h b/src/cpp/model/hedera/CryptoTransferTransaction.h new file mode 100644 index 000000000..04aacafea --- /dev/null +++ b/src/cpp/model/hedera/CryptoTransferTransaction.h @@ -0,0 +1,40 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for creating a hedera transfer transaction +* +*/ + +#include "../../proto/hedera/CryptoTransfer.pb.h" +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + class CryptoTransferTransaction + { + public: + CryptoTransferTransaction(); + ~CryptoTransferTransaction(); + + void addSender(Poco::AutoPtr senderAccountId, Poco::UInt64 amountTinybars); + void addReceiver(Poco::AutoPtr receiverAccountId, Poco::UInt64 amountTinybars); + + bool validate(); + // set pointer to zero, after hand over pointer to transaction body + void resetPointer(); + + inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; } + + protected: + proto::CryptoTransferTransactionBody* mCryptoTransfer; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index 39b3700c4..de4fdec99 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -2,18 +2,24 @@ #include "Poco/Timestamp.h" #include "../../SingletonManager/MemoryManager.h" +#include "Transaction.h" +#include "TransactionBody.h" +#include "CryptoTransferTransaction.h" + namespace model { namespace hedera { Query::Query(const controller::NodeServerConnection& connection) - : mConnection(connection) + : mConnection(connection), mTransactionBody(nullptr) { } Query::~Query() { - + if (mTransactionBody) { + delete mTransactionBody; + } } Query* Query::getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection) @@ -26,58 +32,46 @@ namespace model { accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); query_header->set_responsetype(proto::COST_ANSWER); - auto transaction = query_header->mutable_payment(); + + query->mTransactionBody = new TransactionBody(accountId, connection); + CryptoTransferTransaction crypto_transaction; + crypto_transaction.addSender(accountId, 0); + crypto_transaction.addReceiver(connection.hederaId, 0); + query->mTransactionBody->setCryptoTransfer(crypto_transaction); + + //auto transaction = query_header->mutable_payment(); //auto transaction_body = transaction->mutable_body(); // body content - // transaction id - auto transaction_id = query->mTransactionBody.mutable_transactionid(); - auto timestamp = transaction_id->mutable_transactionvalidstart(); - Poco::Timestamp now; - auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 - timestamp->set_seconds(now.epochTime()); - timestamp->set_nanos(microseconds * 1000); - accountId->copyToProtoAccountId(transaction_id->mutable_accountid()); - // - // sdk default, but can be changed - query->mTransactionBody.set_transactionfee(100000000); - auto valid_duration = query->mTransactionBody.mutable_transactionvalidduration(); - // maximal 2 minutes - valid_duration->set_seconds(120); - auto crypto_transfer = query->mTransactionBody.mutable_cryptotransfer(); - auto transfer_list = crypto_transfer->mutable_transfers(); - auto account_amounts = transfer_list->mutable_accountamounts(); - account_amounts->Add(); - auto account_amount = account_amounts->Mutable(0); - account_amount->set_amount(1000); - connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); + // node account id + return query; } bool Query::sign(std::unique_ptr keyPairHedera) { - auto mm = MemoryManager::getInstance(); - auto body_bytes = mTransactionBody.SerializeAsString(); - auto transaction = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header()->mutable_payment(); - transaction->set_bodybytes(body_bytes.data()); - auto signature_map = transaction->mutable_sigmap(); - auto signature_pairs = signature_map->mutable_sigpair(); - signature_pairs->Add(); - auto signature_pair = signature_pairs->Mutable(0); - auto public_key = keyPairHedera->getPublicKey(); + Transaction transaction; + auto sign_result = transaction.sign(std::move(keyPairHedera), mTransactionBody); + auto query_header = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header(); + query_header->set_allocated_payment(transaction.getTransaction()); + transaction.resetPointer(); - - auto sign = keyPairHedera->sign(body_bytes); - if (!sign) { - printf("[Query::sign] error signing message\n"); - return false; - } - signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); - signature_pair->set_ed25519(*sign, sign->size()); + return sign_result; + } - mm->releaseMemory(sign); + void Query::setResponseType(proto::ResponseType type) + { + auto get_account_balance = mQueryProto.mutable_cryptogetaccountbalance(); + auto query_header = get_account_balance->mutable_header(); + query_header->set_responsetype(type); - return true; + } + + proto::ResponseType Query::getResponseType() + { + auto get_account_balance = mQueryProto.mutable_cryptogetaccountbalance(); + auto query_header = get_account_balance->mutable_header(); + return query_header->responsetype(); } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index ad9af855a..fa9b06471 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -13,6 +13,7 @@ #include "../../proto/hedera/Query.pb.h" #include "../../controller/NodeServer.h" #include "../../Crypto/KeyPairHedera.h" +#include "TransactionBody.h" namespace model { namespace hedera { @@ -23,13 +24,16 @@ namespace model { static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); bool sign(std::unique_ptr keyPairHedera); + void setResponseType(proto::ResponseType type); + proto::ResponseType getResponseType(); + void setFee(Poco::UInt64 fee); inline const proto::Query* getProtoQuery() const { return &mQueryProto; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } protected: Query(const controller::NodeServerConnection& connection); proto::Query mQueryProto; - proto::TransactionBody mTransactionBody; + TransactionBody* mTransactionBody; controller::NodeServerConnection mConnection; }; } diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp index e69de29bb..a39c5364e 100644 --- a/src/cpp/model/hedera/Response.cpp +++ b/src/cpp/model/hedera/Response.cpp @@ -0,0 +1,32 @@ +#include "Response.h" + +namespace model { + namespace hedera { + Response::Response() + { + } + + Response::~Response() + { + + } + + Poco::UInt64 Response::getAccountBalance() + { + if (isCryptoGetAccountBalanceResponse()) { + auto balance_response = mResponseProto.cryptogetaccountbalance(); + return balance_response.balance(); + } + return 0; + } + + proto::ResponseCodeEnum Response::getResponseCode() + { + if (isCryptoGetAccountBalanceResponse()) { + auto balance_response = mResponseProto.cryptogetaccountbalance(); + return balance_response.header().nodetransactionprecheckcode(); + } + return proto::NOT_SUPPORTED; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h index e69de29bb..779f5e982 100644 --- a/src/cpp/model/hedera/Response.h +++ b/src/cpp/model/hedera/Response.h @@ -0,0 +1,38 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H + +/*! +* @author: Dario Rekowski +* +* @date: 03.09.20 +* +* @brief: class for simply accessing hedera responses +* +*/ + +#include "../../proto/hedera/Response.pb.h" +#include "Poco/Types.h" + +namespace model { + namespace hedera { + class Response + { + public: + Response(); + ~Response(); + + inline proto::Response* getResponsePtr() { return &mResponseProto; } + Poco::UInt64 getAccountBalance(); + proto::ResponseCodeEnum getResponseCode(); + + inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); } + + protected: + proto::Response mResponseProto; + + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index e69de29bb..0dadbcb4c 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -0,0 +1,43 @@ +#include "Transaction.h" + +namespace model { + namespace hedera { + Transaction::Transaction() + : mTransaction(nullptr) + { + mTransaction = new proto::Transaction; + } + + Transaction::~Transaction() + { + if (mTransaction) { + delete mTransaction; + mTransaction = nullptr; + } + } + + bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) + { + auto mm = MemoryManager::getInstance(); + auto transaction_body_proto = transactionBody->getProtoTransactionBody(); + auto body_bytes = transaction_body_proto->SerializeAsString(); + mTransaction->set_bodybytes(body_bytes.data()); + auto signature_map = mTransaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_map->add_sigpair(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + return true; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index e69de29bb..3acf46ff9 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -0,0 +1,38 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing hedera transaction +* +*/ + +#include "../../proto/hedera/Transaction.pb.h" +#include "../../Crypto/KeyPairHedera.h" +#include "TransactionBody.h" + +namespace model { + namespace hedera { + class Transaction + { + public: + Transaction(); + ~Transaction(); + + bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); + + inline proto::Transaction* getTransaction() { return mTransaction; } + void resetPointer() { mTransaction = nullptr; } + + protected: + + proto::Transaction* mTransaction; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index e69de29bb..f1979b6bf 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -0,0 +1,47 @@ +#include "TransactionBody.h" + +namespace model { + namespace hedera { + TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) + { + connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); + auto transaction_id = mTransactionBody.mutable_transactionid(); + operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid()); + mTransactionBody.set_transactionfee(10000); + auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration(); + transaction_valid_duration->set_seconds(120); + + updateTimestamp(); + } + + TransactionBody::~TransactionBody() + { + + } + + bool TransactionBody::setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction) + { + if (cryptoTransferTransaction.validate()) { + mTransactionBody.set_allocated_cryptotransfer(cryptoTransferTransaction.getProtoTransactionBody()); + cryptoTransferTransaction.resetPointer(); + return true; + } + return false; + } + + void TransactionBody::setMemo(const std::string& memo) + { + mTransactionBody.set_memo(memo); + } + + void TransactionBody::updateTimestamp() + { + auto transaction_id = mTransactionBody.mutable_transactionid(); + auto timestamp = transaction_id->mutable_transactionvalidstart(); + Poco::Timestamp now; + auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 + timestamp->set_seconds(now.epochTime()); + timestamp->set_nanos(microseconds * 1000); + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index e69de29bb..3663c4a59 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -0,0 +1,39 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing transaction body for hedera transaction +* +*/ + +#include "../../proto/hedera/TransactionBody.pb.h" +#include "../../controller/NodeServer.h" +#include "CryptoTransferTransaction.h" + +namespace model { + namespace hedera { + class TransactionBody + { + public: + TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection); + ~TransactionBody(); + + void setMemo(const std::string& memo); + + bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + + inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } + + protected: + void updateTimestamp(); + proto::TransactionBody mTransactionBody; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H \ No newline at end of file diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 04ce4ffe4..b71b37a89 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -24,7 +24,7 @@ namespace model { MYSQL_CONDITION_OR }; - class ModelBase : public UniLib::lib::MultithreadContainer, public ErrorList + class ModelBase : public UniLib::lib::MultithreadContainer, public NotificationList { public: ModelBase(int id) :mID(id), mReferenceCount(1) {} diff --git a/src/cpp/tasks/ProcessingTransaction.h b/src/cpp/tasks/ProcessingTransaction.h index de58e5f8c..2bf2beb83 100644 --- a/src/cpp/tasks/ProcessingTransaction.h +++ b/src/cpp/tasks/ProcessingTransaction.h @@ -3,7 +3,7 @@ #include "CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/DRHash.h" #include "../model/TransactionBase.h" @@ -26,7 +26,7 @@ class TransactionCreation; class TransactionTransfer; class SigningTransaction; -class ProcessingTransaction : public UniLib::controller::CPUTask, public ErrorList +class ProcessingTransaction : public UniLib::controller::CPUTask, public NotificationList { friend SigningTransaction; public: diff --git a/src/cpp/tasks/SigningTransaction.h b/src/cpp/tasks/SigningTransaction.h index 4781052cb..30c962bf0 100644 --- a/src/cpp/tasks/SigningTransaction.h +++ b/src/cpp/tasks/SigningTransaction.h @@ -3,7 +3,7 @@ #include "CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../model/TransactionBase.h" #include "../model/User.h" #include "../controller/User.h" @@ -19,7 +19,7 @@ * @desc: Task for signing Transactions */ -class SigningTransaction : public UniLib::controller::CPUTask, public ErrorList +class SigningTransaction : public UniLib::controller::CPUTask, public NotificationList { public: SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser); diff --git a/src/cpp/tasks/Task.cpp b/src/cpp/tasks/Task.cpp index e75b1a53d..07bb4c3fc 100644 --- a/src/cpp/tasks/Task.cpp +++ b/src/cpp/tasks/Task.cpp @@ -1,5 +1,5 @@ #include "Task.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" namespace UniLib { namespace controller { @@ -87,7 +87,7 @@ namespace UniLib { mWorkingMutex.lock(500); } catch (Poco::TimeoutException& ex) { - ErrorList errors; + NotificationList errors; errors.addError(new ParamError("Task::lock", getResourceType(), ex.displayText())); errors.sendErrorsAsEmail(); } diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 5379e4ef4..3e8795d24 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -10,6 +10,8 @@ #include "../controller/HederaId.h" #include "../controller/CryptoKey.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/Success.h" #include "../SingletonManager/SessionManager.h" #include "../ServerConfig.h" @@ -22,6 +24,8 @@ auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Profiler hedera_time; + std::string hedera_time_string; Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); @@ -44,7 +48,9 @@ if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { + hedera_time.reset(); hedera_account[0]->updateBalanceFromHedera(user, this); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } } @@ -148,6 +154,7 @@ %><%@ include file="header_large.cpsp" %> <%= getErrorsHtml() %> +
    From db8c6947232eeb4d853a79ea5f605a2a1dde0c08 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 9 Sep 2020 19:34:00 +0200 Subject: [PATCH 025/195] updates for hedera transactions and saving crypto keys also clear un-encrypted --- skeema/gradido_login/hedera_topics.sql | 1 + src/cpp/Crypto/KeyPairHedera.cpp | 42 ++-- src/cpp/Crypto/KeyPairHedera.h | 8 +- .../HTTPInterface/AdminHederaAccountPage.cpp | 5 +- src/cpp/HTTPInterface/AdminTopicPage.cpp | 180 ++++++++++++++---- src/cpp/controller/CryptoKey.cpp | 62 ++++-- src/cpp/controller/CryptoKey.h | 6 +- src/cpp/controller/HederaAccount.cpp | 12 +- src/cpp/controller/HederaAccount.h | 4 +- src/cpp/controller/HederaRequest.cpp | 12 ++ src/cpp/controller/HederaRequest.h | 1 + src/cpp/controller/HederaTopic.cpp | 26 +++ src/cpp/controller/HederaTopic.h | 38 ++++ src/cpp/main.cpp | 16 +- src/cpp/model/hedera/ConsensusCreateTopic.cpp | 45 +++++ src/cpp/model/hedera/ConsensusCreateTopic.h | 31 +++ .../model/hedera/CryptoCreateTransaction.cpp | 16 ++ .../model/hedera/CryptoCreateTransaction.h | 23 +++ src/cpp/model/hedera/Query.cpp | 6 +- src/cpp/model/hedera/Query.h | 7 +- src/cpp/model/hedera/Transaction.cpp | 1 + src/cpp/model/hedera/Transaction.h | 3 +- src/cpp/model/hedera/TransactionBody.cpp | 15 ++ src/cpp/model/hedera/TransactionBody.h | 9 +- src/cpp/model/table/CryptoKey.cpp | 25 ++- src/cpp/model/table/CryptoKey.h | 12 +- src/cpp/model/table/HederaAccount.cpp | 1 + src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaTopic.cpp | 17 +- src/cpp/model/table/HederaTopic.h | 14 ++ src/cpsp/adminHederaAccount.cpsp | 5 +- src/cpsp/adminTopic.cpsp | 112 ++++++++++- 32 files changed, 651 insertions(+), 105 deletions(-) create mode 100644 src/cpp/controller/HederaTopic.cpp create mode 100644 src/cpp/controller/HederaTopic.h create mode 100644 src/cpp/model/hedera/CryptoCreateTransaction.cpp create mode 100644 src/cpp/model/hedera/CryptoCreateTransaction.h diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index 02f7e3b39..b9adaefc2 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -1,6 +1,7 @@ CREATE TABLE `hedera_topics` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `topic_hedera_id` int unsigned NOT NULL, + `name` VARCHAR(255) NOT NULL DEFAULT '', `auto_renew_account_hedera_id` int unsigned DEFAULT NULL, `auto_renew_period` int unsigned NOT NULL DEFAULT '0', `group_id` int unsigned NOT NULL, diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 27d9731a7..62643cc99 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -10,7 +10,7 @@ KeyPairHedera::KeyPairHedera() } -KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) +KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) : mPrivateKey(nullptr) { auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420"); @@ -19,27 +19,28 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* p auto mm = MemoryManager::getInstance(); if (privateKey) { - switch (privateKey->size()) { + switch (privateKeySize) { case 48: // key with prefix - if (0 == sodium_memcmp(*privateKey, *derPrefixPriv, derPrefixPriv->size())) { + if (0 == sodium_memcmp(privateKey, *derPrefixPriv, derPrefixPriv->size())) { //int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed); auto seed = mm->getFreeMemory(crypto_sign_ed25519_SEEDBYTES); - memcpy(*seed, privateKey->data(derPrefixPriv->size()), crypto_sign_ed25519_SEEDBYTES); - createKeyFromSeed(seed); + memcpy(*seed, &privateKey[derPrefixPriv->size()], crypto_sign_ed25519_SEEDBYTES); + createKeyFromSeed(seed->data(), seed->size()); + mm->releaseMemory(seed); break; } case 32: - createKeyFromSeed(privateKey); + createKeyFromSeed(privateKey, privateKeySize); break; case 64: //mPrivateKey = privateKey; - if (!mPrivateKey || mPrivateKey->size() != privateKey->size()) { + if (!mPrivateKey || mPrivateKey->size() != privateKeySize) { if (mPrivateKey) { mm->releaseMemory(mPrivateKey); } - mPrivateKey = mm->getFreeMemory(privateKey->size()); - memcpy(*mPrivateKey, *privateKey, privateKey->size()); + mPrivateKey = mm->getFreeMemory(privateKeySize); + memcpy(*mPrivateKey, privateKey, privateKeySize); } break; default: @@ -75,11 +76,17 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* p mm->releaseMemory(derPrefixPub); } KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) - : KeyPairHedera(privateKey, publicKey->data(), publicKey->size()) + : KeyPairHedera(privateKey->data(), privateKey->size(), publicKey->data(), publicKey->size()) { } +KeyPairHedera::KeyPairHedera(const std::vector& privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) + : KeyPairHedera(privateKey.data(), privateKey.size(), publicKey, publicKeySize) +{ + +} + KeyPairHedera::~KeyPairHedera() { auto mm = MemoryManager::getInstance(); @@ -90,13 +97,13 @@ KeyPairHedera::~KeyPairHedera() } -void KeyPairHedera::createKeyFromSeed(const MemoryBin* seed) +void KeyPairHedera::createKeyFromSeed(const unsigned char* seed, size_t seedSize) { - assert(seed && seed->size() == crypto_sign_ed25519_SEEDBYTES); + assert(seed && seedSize == crypto_sign_ed25519_SEEDBYTES); auto mm = MemoryManager::getInstance(); auto secret_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES); - crypto_sign_seed_keypair(mPublicKey, *secret_key, *seed); + crypto_sign_seed_keypair(mPublicKey, *secret_key, seed); if (mPrivateKey) { mm->releaseMemory(mPrivateKey); @@ -177,6 +184,15 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtrgetFreeMemory(mPrivateKey->size()); + memcpy(*private_key_copy, *mPrivateKey, mPrivateKey->size()); + return private_key_copy; +} + MemoryBin* KeyPairHedera::getPublicKeyCopy() const { auto mm = MemoryManager::getInstance(); diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index a3e4337e5..b308cbe9e 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -22,8 +22,9 @@ public: //! \param privateKey: copy //! \param publicKey: copy //! - KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); + KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); + KeyPairHedera(const std::vector& privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); ~KeyPairHedera(); @@ -64,13 +65,14 @@ public: inline bool hasPrivateKey() const { return mPrivateKey != nullptr; } - //! \brief only way to get a private key.. encrypted + //! \brief MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; + MemoryBin* getPrivateKeyCopy() const; protected: KeyPairHedera(); - void createKeyFromSeed(const MemoryBin* seed); + void createKeyFromSeed(const unsigned char* seed, size_t seedSize); private: diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index fa99a7b35..54a416bef 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -70,7 +70,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request addError(new Error("Action Update Balance", "hedera id not found")); } else { hedera_time.reset(); - hedera_account[0]->updateBalanceFromHedera(user, this); + hedera_account[0]->hederaAccountGetBalance(user, this); addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } @@ -318,7 +318,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request #line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( gettext("Add Account") ); responseStream << "\">\n"; - responseStream << "\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t
    \n"; responseStream << "
    \n"; // begin include footer.cpsp responseStream << "
    \n"; diff --git a/src/cpp/HTTPInterface/AdminTopicPage.cpp b/src/cpp/HTTPInterface/AdminTopicPage.cpp index d8926093e..66fb252d7 100644 --- a/src/cpp/HTTPInterface/AdminTopicPage.cpp +++ b/src/cpp/HTTPInterface/AdminTopicPage.cpp @@ -7,8 +7,10 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" - -#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + #include "../controller/HederaAccount.h" + #include "../controller/Group.h" + #include "../ServerConfig.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" #include "../ServerConfig.h" @@ -27,20 +29,34 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 12 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" const char* pageName = "Topic"; + auto user = mSession->getNewUser(); + + int auto_renew_period = 604800; // 7 Tage + int auto_renew_account = 0; + int group_id = 0; + + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); + + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } - -#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" bool withMaterialIcons = false; std::ostream& _responseStream = response.send(); Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; responseStream << "\n"; - // begin include header_large.cpsp + // begin include header.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; @@ -48,57 +64,132 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << "\n"; responseStream << "\n"; responseStream << "Gradido Login Server: "; -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" responseStream << ( pageName ); responseStream << "\n"; responseStream << "\n"; -#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" if(withMaterialIcons) { responseStream << "\n"; responseStream << "\n"; -#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" } responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "
    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t
    "; - // end include header_large.cpsp + responseStream << "
    \n"; + responseStream << " "; + // end include header.cpsp responseStream << "\n"; -#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + responseStream << "\n"; +#line 40 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t

    Topic Admin Page

    \n"; responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "\t\n"; + responseStream << "
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t

    Ein neues Topic anlegen

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t
    \n"; responseStream << "
    \n"; // begin include footer.cpsp responseStream << "
    \n"; @@ -124,5 +215,18 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << ""; // end include footer.cpsp responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; if (_compressResponse) _gzipStream.close(); } diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 79d68a62e..aa8df1b8d 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -15,16 +15,25 @@ namespace controller { } - Poco::AutoPtr CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user) + Poco::AutoPtr CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user, bool saveEncrypted/* = true*/) { auto mm = MemoryManager::getInstance(); - auto encrypted_priv_key = hederaKeyPair->getCryptedPrivKey(user->getPassword()); + MemoryBin* private_key = nullptr; auto public_key = hederaKeyPair->getPublicKeyCopy(); - auto db = new model::table::CryptoKey(encrypted_priv_key, public_key, model::table::KEY_TYPE_ED25519_HEDERA); + model::table::KeyType key_type; + if (saveEncrypted) { + key_type = model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED; + private_key = hederaKeyPair->getCryptedPrivKey(user->getPassword()); + } + else { + key_type = model::table::KEY_TYPE_ED25519_HEDERA_CLEAR; + private_key = hederaKeyPair->getPrivateKeyCopy(); + } + auto db = new model::table::CryptoKey(private_key, public_key, key_type); - mm->releaseMemory(encrypted_priv_key); + mm->releaseMemory(private_key); mm->releaseMemory(public_key); auto cryptoKey = new CryptoKey(db); @@ -63,28 +72,49 @@ namespace controller { return nullptr; } - std::unique_ptr CryptoKey::getKeyPair(Poco::AutoPtr user) + std::unique_ptr CryptoKey::getKeyPair(Poco::AutoPtr user) const { auto model = getModel(); - auto password = user->getPassword(); - auto mm = MemoryManager::getInstance(); - if (!password || !model->hasPrivateKeyEncrypted()) { - printf("[CryptoKey::getKeyPair] return null, password empty or no private key\n"); + assert(model); + + if (!model->isEncrypted()) { + return getKeyPair(); + } + + if (!model->hasPrivateKey()) { + printf("[CryptoKey::getKeyPair] return null, no private key\n"); return nullptr; } - MemoryBin* clearPassword = nullptr; - auto encrypted_private_key = model->getPrivateKeyEncrypted(); - auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key); - printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data()); - if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { + + auto password = user->getPassword(); + auto mm = MemoryManager::getInstance(); + if (!password) { + printf("[CryptoKey::getKeyPair] return null, password empty\n"); + } + MemoryBin* clearPrivateKey = nullptr; + auto encrypted_private_key = model->getPrivateKey(); + //auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key); + //printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data()); + if (password->decrypt(model->getPrivateKey(), &clearPrivateKey) != SecretKeyCryptography::AUTH_DECRYPT_OK) { printf("[CryptoKey::getKeyPair] return null, error decrypting\n"); return nullptr; } - auto key_pair = std::make_unique(clearPassword, model->getPublicKey(), model->getPublicKeySize()); - mm->releaseMemory(clearPassword); + auto key_pair = std::make_unique(clearPrivateKey->data(), clearPrivateKey->size(), model->getPublicKey(), model->getPublicKeySize()); + mm->releaseMemory(clearPrivateKey); return key_pair; } + std::unique_ptr CryptoKey::getKeyPair() const + { + auto model = getModel(); + assert(model); + if (!model->hasPrivateKey() || model->isEncrypted()) { + printf("[CryptoKey::getKeyPair] no private key or encrypted\n"); + return nullptr; + } + + return std::make_unique(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize()); + } } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index fc69d042c..ef48c88f1 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -16,7 +16,7 @@ namespace controller { ~CryptoKey(); - static Poco::AutoPtr create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user); + static Poco::AutoPtr create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user, bool saveEncrypted = true); //! if returned ptr is NULL, dataset not found static Poco::AutoPtr load(int id); @@ -26,8 +26,10 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::CryptoKey* getModel() const { return _getModel(); } - std::unique_ptr getKeyPair(Poco::AutoPtr user); + std::unique_ptr getKeyPair(Poco::AutoPtr user) const; + std::unique_ptr getKeyPair() const; protected: diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 6fabe2848..e4873ecf0 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) + bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -132,5 +132,15 @@ namespace controller { return false; } + + std::string HederaAccount::toShortSelectOptionName() + { + std::stringstream ss; + auto model = getModel(); + ss << model::table::HederaAccount::hederaNetworkTypeToString((model::table::HederaNetworkType)model->getNetworkType()) << " "; + ss << mHederaID->getModel()->toString() << " " << ((double)model->getBalance() / 100000000.0) << " Hbar"; + return ss.str(); + } + } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index d76420b78..a9a53d528 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -22,12 +22,14 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + std::string HederaAccount::toShortSelectOptionName(); + inline Poco::AutoPtr getModel() { return _getModel(); } inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); + bool hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 308ffa5e8..64998fa6a 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -59,6 +59,18 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::h return HEDERA_REQUEST_RETURN_OK; } +HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, model::hedera::Response* response) +{ + auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials()); + + grpc::ClientContext context; + std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + + std::chrono::milliseconds(5000); + context.set_deadline(deadline); + + return HEDERA_REQUEST_RETURN_OK; +} + #include "Poco/JSON/Object.h" #include "../lib/JsonRequest.h" diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 327ee7634..34bd304a1 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -31,6 +31,7 @@ public: ~HederaRequest(); HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); + HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response); //! for testing, didn't work server say invalid json :/ HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp new file mode 100644 index 000000000..3885c31d8 --- /dev/null +++ b/src/cpp/controller/HederaTopic.cpp @@ -0,0 +1,26 @@ +#include "HederaTopic.h" +#include "../model/hedera/Transaction.h" + +namespace controller { + HederaTopic::HederaTopic(model::table::HederaTopic* dbModel) + { + mDBModel = dbModel; + } + HederaTopic::~HederaTopic() + { + + } + + Poco::AutoPtr HederaTopic::create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId) + { + auto db = new model::table::HederaTopic(name, autoRenewAccountId, autoRenewPeriod, groupId); + + auto hedera_topic = new HederaTopic(db); + return Poco::AutoPtr(hedera_topic); + } + + Poco::UInt64 HederaTopic::hederaCreateTopic() + { + + } +} \ No newline at end of file diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h new file mode 100644 index 000000000..de5552e39 --- /dev/null +++ b/src/cpp/controller/HederaTopic.h @@ -0,0 +1,38 @@ +#ifndef __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H +#define __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H + +/*! +* +* \author: Dario Rekowski +* +* \date: 03.09.2020 +* +* \brief: Class for Hedera Topic, connct db table with hedera object +* +*/ +#include "TableControllerBase.h" +#include "../model/table/HederaTopic.h" + +namespace controller { + class HederaTopic : public TableControllerBase + { + public: + + ~HederaTopic(); + + static Poco::AutoPtr create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId); + + //! \brief hedera call to create a hedera topic + Poco::UInt64 hederaCreateTopic(); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + HederaTopic(model::table::HederaTopic* dbModel); + + }; + +#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H \ No newline at end of file diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 910db09ff..899779fef 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -45,17 +45,25 @@ int main(int argc, char** argv) printf("[Gradido_LoginServer::main] error loading mnemonic Word List"); return -2; } + printf("[Gradido_LoginServer::main] mnemonic word lists loaded!\n"); if (!ImportantTests::passphraseGenerationAndTransformation()) { printf("test passphrase generation and transformation failed\n"); return -3; } + printf("[Gradido_LoginServer::main] passed important tests\n"); grpc_init(); Gradido_LoginServer app; - auto result = app.run(argc, argv); - - grpc_shutdown(); - return result; + try { + auto result = app.run(argc, argv); + grpc_shutdown(); + return result; + } + catch (Poco::Exception& ex) { + printf("[Gradido_LoginServer::main] exception by starting server: %s\n", ex.displayText().data()); + } + return -1; + } #endif \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp index e69de29bb..6ca423102 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.cpp +++ b/src/cpp/model/hedera/ConsensusCreateTopic.cpp @@ -0,0 +1,45 @@ +#include "ConsensusCreateTopic.h" + +namespace model { + namespace hedera { + ConsensusCreateTopic::ConsensusCreateTopic(Poco::AutoPtr autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod) + : mProtoCreateTopic(nullptr) + { + mProtoCreateTopic = new proto::ConsensusCreateTopicTransactionBody; + auto auto_renew_period = mProtoCreateTopic->mutable_autorenewperiod(); + auto_renew_period->set_seconds(autoRenewPeriod); + + auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount(); + autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account); + + } + ConsensusCreateTopic::~ConsensusCreateTopic() + { + if (mProtoCreateTopic) { + delete mProtoCreateTopic; + mProtoCreateTopic = nullptr; + } + } + + void ConsensusCreateTopic::setAdminKey(const MemoryBin* adminPublicKey) + { + auto admin_key = mProtoCreateTopic->mutable_adminkey(); + auto admin_key_string = admin_key->mutable_ed25519(); + *admin_key_string = std::string((const char)*adminPublicKey, adminPublicKey->size()); + } + void ConsensusCreateTopic::setSubmitKey(const MemoryBin* submitPublicKey) + { + auto submit_key = mProtoCreateTopic->mutable_submitkey(); + auto submit_key_string = submit_key->mutable_ed25519(); + *submit_key_string = std::string((const char)*submitPublicKey, submitPublicKey->size()); + } + + bool ConsensusCreateTopic::validate() + { + if (mProtoCreateTopic->autorenewperiod().seconds() > 86400 && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) { + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.h b/src/cpp/model/hedera/ConsensusCreateTopic.h index e69de29bb..e61da46f3 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.h +++ b/src/cpp/model/hedera/ConsensusCreateTopic.h @@ -0,0 +1,31 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H + +#include "../../proto/hedera/ConsensusCreateTopic.pb.h" +#include "../../SingletonManager/MemoryManager.h" + +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + class ConsensusCreateTopic + { + public: + ConsensusCreateTopic(Poco::AutoPtr autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod); + ~ConsensusCreateTopic(); + + inline void setMemo(const std::string& memo) { mProtoCreateTopic->set_memo(memo); } + void setAdminKey(const MemoryBin* adminPublicKey); + void setSubmitKey(const MemoryBin* submitPublicKey); + + bool validate(); + + inline proto::ConsensusCreateTopicTransactionBody* getProtoTransactionBody() { return mProtoCreateTopic; } + inline void resetPointer() { mProtoCreateTopic = nullptr; } + protected: + proto::ConsensusCreateTopicTransactionBody* mProtoCreateTopic; + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.cpp b/src/cpp/model/hedera/CryptoCreateTransaction.cpp new file mode 100644 index 000000000..696a8d6e7 --- /dev/null +++ b/src/cpp/model/hedera/CryptoCreateTransaction.cpp @@ -0,0 +1,16 @@ +#include "CryptoCreateTransaction.h" + +namespace model { + namespace hedera { + + CryptoCreateTransaction::CryptoCreateTransaction() + { + } + + CryptoCreateTransaction::~CryptoCreateTransaction() + { + + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.h b/src/cpp/model/hedera/CryptoCreateTransaction.h new file mode 100644 index 000000000..e1425ebf5 --- /dev/null +++ b/src/cpp/model/hedera/CryptoCreateTransaction.h @@ -0,0 +1,23 @@ +#ifndef __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H +#define __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H + +#include "../../proto/hedera/CryptoCreate.pb.h" + +namespace model { + namespace hedera { + + class CryptoCreateTransaction + { + public: + CryptoCreateTransaction(); + ~CryptoCreateTransaction(); + + protected: + proto::CryptoCreateTransactionBody* mCryptoCreateBody; + }; + } +} + + + +#endif //__GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index de4fdec99..11a8eb735 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -9,8 +9,8 @@ namespace model { namespace hedera { - Query::Query(const controller::NodeServerConnection& connection) - : mConnection(connection), mTransactionBody(nullptr) + Query::Query() + : mTransactionBody(nullptr) { } @@ -27,7 +27,7 @@ namespace model { assert(!accountId.isNull() && accountId->getModel()); - auto query = new Query(connection); + auto query = new Query; auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance(); accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index fa9b06471..376528314 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -26,15 +26,14 @@ namespace model { void setResponseType(proto::ResponseType type); proto::ResponseType getResponseType(); - void setFee(Poco::UInt64 fee); + inline const proto::Query* getProtoQuery() const { return &mQueryProto; } - inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } + inline std::string getConnectionString() const { return mTransactionBody->getConnectionString(); } protected: - Query(const controller::NodeServerConnection& connection); + Query(); proto::Query mQueryProto; TransactionBody* mTransactionBody; - controller::NodeServerConnection mConnection; }; } } diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index 0dadbcb4c..4699e71ea 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -19,6 +19,7 @@ namespace model { bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) { auto mm = MemoryManager::getInstance(); + mConnection = transactionBody->getConnection(); auto transaction_body_proto = transactionBody->getProtoTransactionBody(); auto body_bytes = transaction_body_proto->SerializeAsString(); mTransaction->set_bodybytes(body_bytes.data()); diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index 3acf46ff9..d5e9434bd 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -25,11 +25,12 @@ namespace model { bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); inline proto::Transaction* getTransaction() { return mTransaction; } + inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } void resetPointer() { mTransaction = nullptr; } protected: - proto::Transaction* mTransaction; + controller::NodeServerConnection mConnection; }; } } diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index f1979b6bf..f215ada23 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -3,6 +3,7 @@ namespace model { namespace hedera { TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) + : mConnection(connection) { connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); auto transaction_id = mTransactionBody.mutable_transactionid(); @@ -29,10 +30,24 @@ namespace model { return false; } + bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction) + { + if (consensusCreateTopicTransaction.validate()) { + mTransactionBody.set_allocated_consensuscreatetopic(consensusCreateTopicTransaction.getProtoTransactionBody()); + consensusCreateTopicTransaction.resetPointer(); + return true; + } + return false; + } + void TransactionBody::setMemo(const std::string& memo) { mTransactionBody.set_memo(memo); } + void TransactionBody::setFee(Poco::UInt64 fee) + { + mTransactionBody.set_transactionfee(fee); + } void TransactionBody::updateTimestamp() { diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 3663c4a59..ba421e014 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -13,6 +13,7 @@ #include "../../proto/hedera/TransactionBody.pb.h" #include "../../controller/NodeServer.h" #include "CryptoTransferTransaction.h" +#include "ConsensusCreateTopic.h" namespace model { namespace hedera { @@ -23,14 +24,20 @@ namespace model { ~TransactionBody(); void setMemo(const std::string& memo); - + void setFee(Poco::UInt64 fee); + bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction); + //bool inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } + inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } + inline controller::NodeServerConnection getConnection() const { return mConnection; } protected: void updateTimestamp(); proto::TransactionBody mTransactionBody; + controller::NodeServerConnection mConnection; }; } } diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index 9588f57e7..a4f1034e3 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -43,12 +43,33 @@ namespace model { const char* CryptoKey::typeToString(KeyType type) { switch (type) { - case KEY_TYPE_ED25519_SODIUM: return "ed25519 ref10"; - case KEY_TYPE_ED25519_HEDERA: return "sodium ed22519"; + case KEY_TYPE_ED25519_SODIUM_ENCRYPTED: return "ed25519 sodium encrypted"; + case KEY_TYPE_ED25519_HEDERA_ENCRYPTED: return "ed22519 for hedera encrypted"; + case KEY_TYPE_ED25519_SODIUM_CLEAR: return "ed25519 sodium clear"; + case KEY_TYPE_ED25519_HEDERA_CLEAR: return "ed25519 hedera clear"; } return ""; } + bool CryptoKey::hasPrivateKeyEncrypted() const + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED || type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + return !mPrivateKey.isNull(); + } + return false; + } + + bool CryptoKey::isEncrypted() const + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED || + type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + return true; + } + return false; + } + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index 7e50fc728..c1fa0b66d 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -8,8 +8,10 @@ namespace model { namespace table { enum KeyType { - KEY_TYPE_ED25519_SODIUM = 0, - KEY_TYPE_ED25519_HEDERA = 1, + KEY_TYPE_ED25519_SODIUM_ENCRYPTED = 0, + KEY_TYPE_ED25519_HEDERA_ENCRYPTED = 1, + KEY_TYPE_ED25519_SODIUM_CLEAR = 2, + KEY_TYPE_ED25519_HEDERA_CLEAR = 3, KEY_TYPE_COUNT }; @@ -27,8 +29,10 @@ namespace model { inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } - inline bool hasPrivateKeyEncrypted() const { return !mPrivateKey.isNull(); } - inline const std::vector& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); } + bool hasPrivateKeyEncrypted() const; + bool isEncrypted() const; + inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); } + inline const std::vector& getPrivateKey() const { return mPrivateKey.value().content(); } static const char* typeToString(KeyType type); protected: diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 1485ff554..2479c09cc 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -44,6 +44,7 @@ namespace model { return ss.str(); } + const char* HederaAccount::hederaNetworkTypeToString(HederaNetworkType type) { switch (type) { diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 4d4dd6575..6b0d636a0 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -28,6 +28,7 @@ namespace model { // generic db operations const char* getTableName() const { return "hedera_accounts"; } std::string toString(); + static const char* hederaNetworkTypeToString(HederaNetworkType type); static NodeServerType networkTypeToNodeServerType(HederaNetworkType type); diff --git a/src/cpp/model/table/HederaTopic.cpp b/src/cpp/model/table/HederaTopic.cpp index ef80ea071..b91ea0864 100644 --- a/src/cpp/model/table/HederaTopic.cpp +++ b/src/cpp/model/table/HederaTopic.cpp @@ -5,6 +5,14 @@ using namespace Poco::Data::Keywords; namespace model { namespace table { HederaTopic::HederaTopic() + : mTopicHederaId(0), mAutoRenewAccountHederaId(0), mAutoRenewPeriod(0), mGroupId(0), mAdminKeyId(0), mSubmitKeyId(0),mSequenceNumber(0) + { + + } + + HederaTopic::HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId) + : mTopicHederaId(0), mName(name), mAutoRenewAccountHederaId(autoRenewAccountId), mAutoRenewPeriod(autoRenewAccountId), mGroupId(groupId), + mAdminKeyId(0), mSubmitKeyId(0), mSequenceNumber(0) { } @@ -18,6 +26,7 @@ namespace model { { std::stringstream ss; ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl; + ss << "Name: " << mName << std::endl; ss << "Auto Renew Account Hedera id: " << std::to_string(mAutoRenewAccountHederaId) << std::endl; ss << "Auto Renew Period: " << std::to_string(mAutoRenewPeriod) << " seconds" << std::endl; ss << "Group id: " << std::to_string(mGroupId) << std::endl; @@ -33,10 +42,10 @@ namespace model { { Poco::Data::Statement select(session); - select << "SELECT id, topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period, " + select << "SELECT id, topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period, " << "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName() << " where " << fieldName << " = ?" - , into(mID), into(mTopicHederaId), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod) + , into(mID), into(mTopicHederaId), into(mName), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod) , into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated); return select; @@ -57,9 +66,9 @@ namespace model { Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period," + << " (topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period," << " group_id, admin_key_id, submit_key_id, current_timeout, sequence_number) VALUES(?,?,?,?,?,?,?,?)" - , use(mTopicHederaId), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod) + , use(mTopicHederaId), use(mName), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod) , use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber), use(mUpdated); unlock(); return insert; diff --git a/src/cpp/model/table/HederaTopic.h b/src/cpp/model/table/HederaTopic.h index fe5cc342b..3c8cb6f16 100644 --- a/src/cpp/model/table/HederaTopic.h +++ b/src/cpp/model/table/HederaTopic.h @@ -10,12 +10,25 @@ namespace model { { public: HederaTopic(); + HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId); ~HederaTopic(); // generic db operations const char* getTableName() const { return "hedera_topics"; } std::string toString(); + inline Poco::UInt32 getTopicHederaId() const { return mTopicHederaId; } + inline std::string getName() const { return mName; } + inline Poco::UInt32 getAutoRenewAccountId() const { return mAutoRenewAccountHederaId; } + inline Poco::UInt32 getAutoRenewPeriod() const { return mAutoRenewPeriod; } + inline Poco::UInt32 getGroupId() const { return mGroupId;} + inline Poco::DateTime getCurrentTimoout() const { return mCurrentTimeout; } + inline Poco::UInt64 getSequenceNumber() const { return mSequenceNumber; } + inline Poco::DateTime getUpdated() const { return mUpdated; } + + inline void setTopicHederaID(Poco::UInt32 topidHederaId) { mTopicHederaId = topidHederaId;} + inline void setSequeceNumber(Poco::UInt64 sequenceNumber) { mSequenceNumber = sequenceNumber; } + inline void setCurrentTimeout(Poco::DateTime currentTimeOut) { mCurrentTimeout = currentTimeOut; } protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); @@ -23,6 +36,7 @@ namespace model { Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); Poco::UInt32 mTopicHederaId; + std::string mName; Poco::UInt32 mAutoRenewAccountHederaId; // in seconds Poco::UInt32 mAutoRenewPeriod; diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 3e8795d24..95d6992b7 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -49,7 +49,7 @@ addError(new Error("Action Update Balance", "hedera id not found")); } else { hedera_time.reset(); - hedera_account[0]->updateBalanceFromHedera(user, this); + hedera_account[0]->hederaAccountGetBalance(user, this); addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } @@ -204,6 +204,7 @@ <% } %> "> - + +
    <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/adminTopic.cpsp b/src/cpsp/adminTopic.cpsp index 3eac5a976..ffef4ea18 100644 --- a/src/cpsp/adminTopic.cpsp +++ b/src/cpsp/adminTopic.cpsp @@ -5,19 +5,123 @@ <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> <%! - + #include "../controller/HederaAccount.h" + #include "../controller/Group.h" + #include "../SingletonManager/SessionManager.h" + #include "../ServerConfig.h" + #include "../lib/DataTypeConverter.h" %> <%% const char* pageName = "Topic"; + auto user = mSession->getNewUser(); + auto sm = SessionManager::getInstance(); + + std::string name = ""; + int auto_renew_account = 0; + int auto_renew_period = 604800; // 7 Tage + + int group_id = 0; + if(!form.empty()) { + name = form.get("topic-name", ""); + auto auto_renew_account_string = form.get("topic-auto-renew-account", "0"); + auto auto_renew_period_string = form.get("topic-auto-renew-period", "604800"); + auto group_id_string = form.get("topic-group", "-1"); + + if(name != "" && !sm->isValid(name, VALIDATE_NAME)) { + addError(new Error("Topic", "Name not valid, at least 3 Character")); + } + + if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Topic", "auto renew account id not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew account id to int")); + } + } + + if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Topic", "auto renew period not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew period to int")); + } + } -%><%@ include file="header_large.cpsp" %> + if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Topic", "group_id not an integer")); + } else { + if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting group_id to int")); + } + } + } + + + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); + + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } + + +%><%@ include file="header.cpsp" %> + <%= getErrorsHtml() %>

    Topic Admin Page

    -
    - +
    +
    +

    Ein neues Topic anlegen

    +
    +
    +
    + + + + + +
    + + + + "> + +
    <%@ include file="footer.cpsp" %> + + \ No newline at end of file From 941d66fc6a89446b725c40b412f932b1571ae0b4 Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 10 Sep 2020 11:11:37 +0200 Subject: [PATCH 026/195] fix compile error (missing }) --- src/cpp/controller/HederaTopic.cpp | 4 ++-- src/cpp/controller/HederaTopic.h | 1 + src/cpp/model/hedera/ConsensusCreateTopic.cpp | 4 +++- src/cpp/model/hedera/ConsensusCreateTopic.h | 5 +++-- src/cpp/model/hedera/TransactionBody.h | 4 +++- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp index 3885c31d8..31d18a94c 100644 --- a/src/cpp/controller/HederaTopic.cpp +++ b/src/cpp/controller/HederaTopic.cpp @@ -1,5 +1,5 @@ #include "HederaTopic.h" -#include "../model/hedera/Transaction.h" +//#include "../model/hedera/Transaction.h" namespace controller { HederaTopic::HederaTopic(model::table::HederaTopic* dbModel) @@ -21,6 +21,6 @@ namespace controller { Poco::UInt64 HederaTopic::hederaCreateTopic() { - + return 0; } } \ No newline at end of file diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h index de5552e39..4c2ebefb6 100644 --- a/src/cpp/controller/HederaTopic.h +++ b/src/cpp/controller/HederaTopic.h @@ -34,5 +34,6 @@ namespace controller { HederaTopic(model::table::HederaTopic* dbModel); }; +} #endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp index 6ca423102..a20985593 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.cpp +++ b/src/cpp/model/hedera/ConsensusCreateTopic.cpp @@ -1,3 +1,5 @@ + + #include "ConsensusCreateTopic.h" namespace model { @@ -42,4 +44,4 @@ namespace model { return false; } } -} \ No newline at end of file +} diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.h b/src/cpp/model/hedera/ConsensusCreateTopic.h index e61da46f3..b639ee305 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.h +++ b/src/cpp/model/hedera/ConsensusCreateTopic.h @@ -1,10 +1,10 @@ #ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H #define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H -#include "../../proto/hedera/ConsensusCreateTopic.pb.h" -#include "../../SingletonManager/MemoryManager.h" +#include "../../SingletonManager/MemoryManager.h" #include "../../controller/HederaId.h" +#include "../../proto/hedera/ConsensusCreateTopic.pb.h" namespace model { namespace hedera { @@ -28,4 +28,5 @@ namespace model { } } + #endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index ba421e014..7be8d2105 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -10,11 +10,13 @@ * */ -#include "../../proto/hedera/TransactionBody.pb.h" + #include "../../controller/NodeServer.h" #include "CryptoTransferTransaction.h" #include "ConsensusCreateTopic.h" +#include "../../proto/hedera/TransactionBody.pb.h" + namespace model { namespace hedera { class TransactionBody From eaf95f87e49a81cd239cb75266366d8a413940b4 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 11 Sep 2020 12:29:06 +0200 Subject: [PATCH 027/195] change encryption state of crypto_keys --- skeema/gradido_login/crypto_keys.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 1 + src/cpp/Crypto/KeyPairHedera.h | 3 + .../HTTPInterface/AdminHederaAccountPage.cpp | 139 ++++++++++++------ src/cpp/controller/CryptoKey.cpp | 30 ++++ src/cpp/controller/CryptoKey.h | 11 +- src/cpp/controller/HederaAccount.cpp | 62 ++++++-- src/cpp/controller/HederaAccount.h | 10 +- src/cpp/controller/HederaId.cpp | 10 ++ src/cpp/controller/HederaId.h | 2 + src/cpp/model/table/CryptoKey.cpp | 65 +++++++- src/cpp/model/table/CryptoKey.h | 9 ++ src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaId.cpp | 1 + src/cpp/model/table/ModelBase.cpp | 18 +++ src/cpp/model/table/ModelBase.h | 1 + src/cpsp/adminHederaAccount.cpsp | 101 +++++++++---- 17 files changed, 377 insertions(+), 89 deletions(-) diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index c79987755..1e5d6bad8 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,6 +1,6 @@ CREATE TABLE `crypto_keys` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `private_key` binary(80) NOT NULL, + `private_key` varbinary(80) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`), diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 62643cc99..e3a377864 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -184,6 +184,7 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr password) const; MemoryBin* getPrivateKeyCopy() const; + inline std::string getPrivateKeyHex(const Poco::AutoPtr password) const { if (!mPrivateKey) return "0x0"; return DataTypeConverter::binToHex(mPrivateKey); } protected: diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 54a416bef..3247e1130 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -51,40 +51,58 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); std::string action = ""; - std::string account_id_from_query; + Poco::AutoPtr query_hedera_account; + + // parsing get query params if(uri_query.size() >= 2) { if(uri_query[0].first == "action") { action = uri_query[0].second; } if(uri_query[1].first == "account_id") { + std::string account_id_from_query; + int account_id = 0; account_id_from_query = uri_query[1].second; - } - } - if(action == "updateBalance") { - int account_id = 0; - if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); - } else { - auto hedera_account = controller::HederaAccount::load("id", account_id); - if(!hedera_account.size() || hedera_account[0].isNull()) { - addError(new Error("Action Update Balance", "hedera id not found")); + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); } else { - hedera_time.reset(); - hedera_account[0]->hederaAccountGetBalance(user, this); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + auto hedera_accounts = controller::HederaAccount::load("id", account_id); + if(!hedera_accounts.size() || hedera_accounts[0].isNull()) { + addError(new Error("Action", "hedera account not found")); + } else { + query_hedera_account = hedera_accounts[0]; + } } } } - // add - else if(!form.empty()) { + // actions + if(!query_hedera_account.isNull()) + { + if(action == "updateBalance") + { + hedera_time.reset(); + query_hedera_account->hederaAccountGetBalance(user); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } + else if(action == "changeEncryption") + { + if(query_hedera_account->changeEncryption(user)) { + addNotification(new Success("Hedera Account", "success in changing encryption")); + } + } + } + else if(!form.empty()) // add + { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); auto numString = form.get("account-num", "0"); auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); auto publicKeyString = form.get("account-public-key", ""); auto networkTypeString = form.get("account-network-type", "0"); + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + int shardNum = 0; int realmNum = 0; int num = 0; @@ -144,7 +162,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user); + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); if(!crypto_key->getModel()->insertIntoDB(true)) { addError(new Error("DB Error", "Error saving crypto key in DB")); } @@ -152,15 +170,26 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request printf("crypto key found in db\n"); } if(0 == errorCount()) { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } } } @@ -169,7 +198,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request } } - + if(!query_hedera_account.isNull()) { + getErrors(query_hedera_account); + } // list accounts auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); @@ -231,7 +262,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -244,41 +275,63 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Hedera Id
    \t\t\t\n"; responseStream << "\t\t\t\t
    Balance
    \n"; responseStream << "\t\t\t\t
    Server Type
    \n"; + responseStream << "\t\t\t\t
    Verschlüsselt?
    \n"; responseStream << "\t\t\t\t
    Last Updated
    \n"; responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + std::string changeEncryption(""); + if(hedera_account_model->getUserId() == user->getModel()->getID()) { + changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); + } + //printf("change encryption: %s\n", changeEncryption.data()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + if(changeEncryption != "") { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + } responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -287,7 +340,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -296,26 +349,28 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index aa8df1b8d..338ad05a4 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -113,8 +113,38 @@ namespace controller { return nullptr; } + return std::make_unique(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize()); } + bool CryptoKey::changeEncryption(Poco::AutoPtr user) + { + auto key_pair = getKeyPair(user); + if (!key_pair || !key_pair->hasPrivateKey()) { + addError(new Error("Crypto Key", "key pair or private key was null")); + return false; + } + auto model = getModel(); + auto mm = MemoryManager::getInstance(); + // update key type + model->changeKeyTypeToggleEncrypted(); + MemoryBin* private_key = nullptr; + if (model->isEncrypted()) { + private_key = key_pair->getCryptedPrivKey(user->getPassword()); + } + else { + private_key = key_pair->getPrivateKeyCopy(); + } + if (!private_key) { + addError(new Error("Crypto Key", " private_key not get")); + return false; + } + model->setPrivateKey(private_key); + // save changes into db + model->updatePrivkeyAndKeyType(); + + mm->releaseMemory(private_key); + return true; + } } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index ef48c88f1..ddd2a7435 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -9,9 +9,15 @@ #include "TableControllerBase.h" #include "User.h" + + namespace controller { - class CryptoKey : public TableControllerBase + + class HederaAccount; + + class CryptoKey : public TableControllerBase, public NotificationList { + friend HederaAccount; public: ~CryptoKey(); @@ -31,8 +37,11 @@ namespace controller { std::unique_ptr getKeyPair(Poco::AutoPtr user) const; std::unique_ptr getKeyPair() const; + protected: + + bool changeEncryption(Poco::AutoPtr user); CryptoKey(model::table::CryptoKey* dbModel); }; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index e4873ecf0..22a82c929 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -40,6 +40,20 @@ namespace controller { return resultVector; } + Poco::AutoPtr HederaAccount::load(Poco::AutoPtr hederaId) + { + if (!hederaId->isExistInDB()) return nullptr; + + auto db = new model::table::HederaAccount(); + auto result_count = db->loadFromDB("account_hedera_id", hederaId->getModel()->getID()); + if (1 == result_count) { + return new HederaAccount(db); + } + // maybe change later to using error manager and send email + printf("[HederaAccount::load] result_count not expected: %d\n", result_count); + return nullptr; + } + std::vector> HederaAccount::listAll() { auto db = new model::table::HederaAccount(); @@ -73,7 +87,13 @@ namespace controller { return resultVector; } - bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) + Poco::AutoPtr HederaAccount::getCryptoKey() const + { + auto model = getModel(); + return controller::CryptoKey::load(model->getCryptoKeyId()); + } + + bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -86,13 +106,13 @@ namespace controller { auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); if (crypto_key.isNull()) { - if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));} - else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); } + addError(new Error("Keys", "could not found crypto key for account")); + printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); return false; } auto hedera_key_pair = crypto_key->getKeyPair(user); if (!hedera_key_pair) { - if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));} + addError(new Error("Keys", "error decrypting private key")); printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); return false; } @@ -111,13 +131,8 @@ namespace controller { account_model->updateIntoDB("balance", response.getAccountBalance()); } else { - if (errorReceiver) { - errorReceiver->addError(new Error("Hedera", "Hedera request failed")); - errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); - } - else { - printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data()); - } + addError(new Error("Hedera", "Hedera request failed")); + addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); } //request.requestViaPHPRelay(query); } @@ -125,13 +140,32 @@ namespace controller { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } - if (errorReceiver) { - errorReceiver->getErrors(&request); - } + getErrors(&request); return false; } + bool HederaAccount::changeEncryption(Poco::AutoPtr user) + { + assert(!user.isNull() && user->getModel()); + auto model = getModel(); + assert(!model.isNull()); + + if (user->getModel()->getID() != model->getUserId()) { + addError(new Error("Hedera Account", "wrong user")); + return false; + } + auto crypto_key = controller::CryptoKey::load(model->getCryptoKeyId()); + if (crypto_key.isNull()) { + addError(new Error("Hedera Account", "couldn't find crypto key")); + return false; + } + bool result = crypto_key->changeEncryption(user); + getErrors(crypto_key); + return result; + + } + std::string HederaAccount::toShortSelectOptionName() { diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index a9a53d528..77f34aa87 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -8,9 +8,10 @@ #include "Poco/SharedPtr.h" #include "TableControllerBase.h" +#include "CryptoKey.h" namespace controller { - class HederaAccount : public TableControllerBase + class HederaAccount : public TableControllerBase, public NotificationList { public: ~HederaAccount(); @@ -18,6 +19,7 @@ namespace controller { static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); static std::vector> load(const std::string& fieldName, int fieldValue); + static Poco::AutoPtr load(Poco::AutoPtr hederaId); static std::vector> listAll(); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } @@ -25,11 +27,15 @@ namespace controller { std::string HederaAccount::toShortSelectOptionName(); inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::HederaAccount* getModel() const { return _getModel(); } inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); + Poco::AutoPtr getCryptoKey() const; + + bool hederaAccountGetBalance(Poco::AutoPtr user); + bool changeEncryption(Poco::AutoPtr user); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index ce171a7a8..de2cf1dfa 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -37,4 +37,14 @@ namespace controller { protoAccountId->set_realmnum(model->getRealmNum()); protoAccountId->set_accountnum(model->getNum()); } + + bool HederaId::isExistInDB() + { + auto model = getModel(); + if (model->getID() > 0) return true; + //std::vector loadFromDB(const std::vector& fieldNames, const std::vector& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0); + model->isExistInDB(); + return model->getID() != 0; + + } } \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index ae9296a43..1cf967927 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -20,6 +20,8 @@ namespace controller { static Poco::AutoPtr load(int id); + bool isExistInDB(); + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index a4f1034e3..f461edc02 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -1,5 +1,5 @@ #include "CryptoKey.h" -#include "../../lib/DataTypeConverter.h" + using namespace Poco::Data::Keywords; namespace model { @@ -51,6 +51,8 @@ namespace model { return ""; } + + bool CryptoKey::hasPrivateKeyEncrypted() const { const KeyType type = (KeyType)(mKeyType); @@ -70,6 +72,39 @@ namespace model { return false; } + void CryptoKey::setPrivateKey(const MemoryBin* privateKey) + { + if (!privateKey) { + mPrivateKey = Poco::Nullable(); + } + else { + mPrivateKey = Poco::Nullable(Poco::Data::BLOB(*privateKey, privateKey->size())); + } + + } + + bool CryptoKey::changeKeyTypeToggleEncrypted() + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + mKeyType = KEY_TYPE_ED25519_SODIUM_CLEAR; + return true; + } + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED) { + mKeyType = KEY_TYPE_ED25519_HEDERA_CLEAR; + return true; + } + if (type == KEY_TYPE_ED25519_SODIUM_CLEAR) { + mKeyType = KEY_TYPE_ED25519_SODIUM_ENCRYPTED; + return true; + } + if (type == KEY_TYPE_ED25519_HEDERA_CLEAR) { + mKeyType = KEY_TYPE_ED25519_HEDERA_ENCRYPTED; + return true; + } + return false; + } + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -103,5 +138,33 @@ namespace model { unlock(); return insert; } + + size_t CryptoKey::updatePrivkeyAndKeyType() + { + Poco::ScopedLock _lock(mWorkMutex); + if (mPrivateKey.isNull() || !mID) { + return 0; + } + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement update(session); + + update << "UPDATE " << getTableName() << " SET private_key = ?, crypto_key_type_id = ? where id = ?;", + use(mPrivateKey), use(mKeyType), use(mID); + + + size_t resultCount = 0; + try { + return update.execute(); + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "[updatePrivkeyAndKeyType] mysql error by update", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: \n", toString().data())); + } + //printf("data valid: %s\n", toString().data()); + return 0; + } + } } \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index c1fa0b66d..0dcbb618f 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -3,6 +3,7 @@ #include "ModelBase.h" #include "Poco/Types.h" +#include "../../lib/DataTypeConverter.h" namespace model { namespace table { @@ -27,13 +28,21 @@ namespace model { std::string toString(); inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + inline std::string getPublicKeyHexString() const { return DataTypeConverter::binToHex(mPublicKey); }; size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } bool hasPrivateKeyEncrypted() const; bool isEncrypted() const; + bool changeKeyTypeToggleEncrypted(); inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); } inline const std::vector& getPrivateKey() const { return mPrivateKey.value().content(); } + size_t updatePrivkeyAndKeyType(); + + //! \brief set encrypted private key + //! \param privateKey copy data, didn't move memory bin + void setPrivateKey(const MemoryBin* privateKey); + static const char* typeToString(KeyType type); protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 6b0d636a0..699330adf 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -35,6 +35,7 @@ namespace model { inline int getAccountHederaId() const { return mAccountHederaId; } inline int getCryptoKeyId() const { return mAccountKeyId; } + inline int getUserId() const { return mUserId; } inline Poco::UInt64 getBalance() { return mBalance; } inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index 9f26f05c5..d6ceb8cb7 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -55,6 +55,7 @@ namespace model { return mID; } + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index 7bb7301f6..49b470d7a 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -78,6 +78,24 @@ namespace model { return false; } + bool ModelBase::isExistInDB() + { + auto cm = ConnectionManager::getInstance(); + Poco::ScopedLock _lock(mWorkMutex); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement select = _loadIdFromDB(session); + try { + select.executeAsync(); + return select.wait() == 1; + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "mysql error by select id, check if exist in db", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: ", toString().data())); + } + return false; + } + bool ModelBase::deleteFromDB() { Poco::ScopedLock _lock(mWorkMutex); diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index b71b37a89..7be066b31 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -40,6 +40,7 @@ namespace model { size_t loadFromDB(const std::string& fieldName, const T& fieldValue); template bool isExistInDB(const std::string& fieldName, const T& fieldValue); + bool isExistInDB(); template std::vector loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0); template diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 95d6992b7..b55701b1b 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -30,40 +30,58 @@ Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); std::string action = ""; - std::string account_id_from_query; + Poco::AutoPtr query_hedera_account; + + // parsing get query params if(uri_query.size() >= 2) { if(uri_query[0].first == "action") { action = uri_query[0].second; } if(uri_query[1].first == "account_id") { + std::string account_id_from_query; + int account_id = 0; account_id_from_query = uri_query[1].second; - } - } - if(action == "updateBalance") { - int account_id = 0; - if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); - } else { - auto hedera_account = controller::HederaAccount::load("id", account_id); - if(!hedera_account.size() || hedera_account[0].isNull()) { - addError(new Error("Action Update Balance", "hedera id not found")); + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); } else { - hedera_time.reset(); - hedera_account[0]->hederaAccountGetBalance(user, this); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + auto hedera_accounts = controller::HederaAccount::load("id", account_id); + if(!hedera_accounts.size() || hedera_accounts[0].isNull()) { + addError(new Error("Action", "hedera account not found")); + } else { + query_hedera_account = hedera_accounts[0]; + } } } } - // add - else if(!form.empty()) { + // actions + if(!query_hedera_account.isNull()) + { + if(action == "updateBalance") + { + hedera_time.reset(); + query_hedera_account->hederaAccountGetBalance(user); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } + else if(action == "changeEncryption") + { + if(query_hedera_account->changeEncryption(user)) { + addNotification(new Success("Hedera Account", "success in changing encryption")); + } + } + } + else if(!form.empty()) // add + { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); auto numString = form.get("account-num", "0"); auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); auto publicKeyString = form.get("account-public-key", ""); auto networkTypeString = form.get("account-network-type", "0"); + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + int shardNum = 0; int realmNum = 0; int num = 0; @@ -123,7 +141,7 @@ auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user); + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); if(!crypto_key->getModel()->insertIntoDB(true)) { addError(new Error("DB Error", "Error saving crypto key in DB")); } @@ -131,15 +149,26 @@ printf("crypto key found in db\n"); } if(0 == errorCount()) { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } } } @@ -148,7 +177,9 @@ } } - + if(!query_hedera_account.isNull()) { + getErrors(query_hedera_account); + } // list accounts auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); @@ -165,21 +196,33 @@
    Hedera Id
    Balance
    Server Type
    +
    Verschlüsselt?
    Last Updated
    Aktionen
    <% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + std::string changeEncryption(""); + if(hedera_account_model->getUserId() == user->getModel()->getID()) { + changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); + } + //printf("change encryption: %s\n", changeEncryption.data()); %>
    <%= (*it)->getHederaId()->getModel()->toString() %>
    <%= hedera_account_model->getBalanceDouble() %> hbar
    <%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
    +
    <%= (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" %>
    <%= hedera_account_model->getUpdatedString() %>
    - + <% if(changeEncryption != "") { %> + + <% } %>
    <% } %>
    @@ -195,6 +238,8 @@ + + From 7449f73e89ccb6d1cae09716eac5bc9d6ee7e8f0 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 14 Sep 2020 21:09:18 +0200 Subject: [PATCH 028/195] Update code for sending transaction over hedera --- src/cpp/Crypto/KeyPairHedera.cpp | 18 + src/cpp/Crypto/KeyPairHedera.h | 7 +- .../HTTPInterface/AdminHederaAccountPage.cpp | 364 ++++++++++++------ .../SingletonManager/HederaTaskManager.cpp | 17 + src/cpp/SingletonManager/HederaTaskManager.h | 23 ++ src/cpp/SingletonManager/SessionManager.cpp | 1 + src/cpp/SingletonManager/SessionManager.h | 1 + src/cpp/controller/HederaAccount.cpp | 75 +++- src/cpp/controller/HederaAccount.h | 9 + src/cpp/controller/HederaId.cpp | 47 +++ src/cpp/controller/HederaId.h | 6 + src/cpp/controller/HederaRequest.cpp | 28 ++ src/cpp/controller/HederaRequest.h | 7 + src/cpp/controller/HederaTopic.cpp | 2 + src/cpp/controller/HederaTopic.h | 4 +- src/cpp/lib/DataTypeConverter.cpp | 28 ++ src/cpp/lib/DataTypeConverter.h | 1 + .../model/hedera/ConsensusSubmitMessage.cpp | 42 ++ src/cpp/model/hedera/ConsensusSubmitMessage.h | 32 ++ .../model/hedera/CryptoCreateTransaction.cpp | 22 +- .../model/hedera/CryptoCreateTransaction.h | 10 +- .../hedera/CryptoTransferTransaction.cpp | 5 - .../model/hedera/CryptoTransferTransaction.h | 2 +- src/cpp/model/hedera/Transaction.cpp | 29 ++ src/cpp/model/hedera/Transaction.h | 3 + src/cpp/model/hedera/TransactionBody.cpp | 46 ++- src/cpp/model/hedera/TransactionBody.h | 16 + src/cpp/model/hedera/TransactionResponse.cpp | 18 + src/cpp/model/hedera/TransactionResponse.h | 30 ++ src/cpp/model/table/HederaId.cpp | 7 + src/cpp/model/table/HederaId.h | 4 +- src/cpp/tasks/HederaTask.cpp | 0 src/cpp/tasks/HederaTask.h | 15 + src/cpp/tasks/SigningTransaction.cpp | 41 ++ src/cpsp/adminHederaAccount.cpsp | 291 +++++++++----- 35 files changed, 1009 insertions(+), 242 deletions(-) create mode 100644 src/cpp/SingletonManager/HederaTaskManager.cpp create mode 100644 src/cpp/SingletonManager/HederaTaskManager.h create mode 100644 src/cpp/model/hedera/TransactionResponse.cpp create mode 100644 src/cpp/model/hedera/TransactionResponse.h create mode 100644 src/cpp/tasks/HederaTask.cpp create mode 100644 src/cpp/tasks/HederaTask.h diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index e3a377864..c2738e886 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -96,6 +96,24 @@ KeyPairHedera::~KeyPairHedera() } } +KeyPairHedera* KeyPairHedera::create() +{ + /* + The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) + and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + + assert(getPublicKeySize() == crypto_sign_PUBLICKEYBYTES); + + auto mm = MemoryManager::getInstance(); + auto private_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES); + auto public_key = mm->getFreeMemory(getPublicKeySize()); + + crypto_sign_keypair(*public_key, *private_key); + return new KeyPairHedera(private_key, public_key); +} + void KeyPairHedera::createKeyFromSeed(const unsigned char* seed, size_t seedSize) { diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 4613618c5..769f29af6 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -26,6 +26,9 @@ public: KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); KeyPairHedera(const std::vector& privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); + + + static KeyPairHedera* create(); ~KeyPairHedera(); @@ -43,12 +46,12 @@ public: const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;} inline bool isTheSame(const KeyPairHedera& b) const { - return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); + return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, getPublicKeySize()); } inline bool isTheSame(const unsigned char* pubkey) const { if (!pubkey) return false; - return 0 == sodium_memcmp(mPublicKey, pubkey, ed25519_pubkey_SIZE); + return 0 == sodium_memcmp(mPublicKey, pubkey, getPublicKeySize()); } //! \return 0 if the same //! \return -1 if not the same diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 3247e1130..5ff4f7218 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -45,6 +45,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + int auto_renew_period = 604800; // 7 Tage + int auto_renew_account = 0; + double initial_balance = 0.0; Profiler hedera_time; std::string hedera_time_string; @@ -80,8 +83,11 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(action == "updateBalance") { hedera_time.reset(); - query_hedera_account->hederaAccountGetBalance(user); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + if(query_hedera_account->hederaAccountGetBalance(user)) { + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } else { + addError(new ParamError("Hedera", "crypto get balance failed in ", hedera_time.string())); + } } else if(action == "changeEncryption") { @@ -90,113 +96,150 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request } } } - else if(!form.empty()) // add + else if(!form.empty()) // add or create { - // collect - auto shardNumString = form.get("account-shard-num", "0"); - auto realmNumString = form.get("account-realm-num", "0"); - auto numString = form.get("account-num", "0"); - auto privateKeyString = form.get("account-private-key", ""); - auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); - auto publicKeyString = form.get("account-public-key", ""); - auto networkTypeString = form.get("account-network-type", "0"); + auto creationButton = form.get("create",""); + if(creationButton != "") { - //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); - - int shardNum = 0; - int realmNum = 0; - int num = 0; - int networkType = 0; - - MemoryBin* private_key = nullptr; - MemoryBin* public_key = nullptr; - - // validate - if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "shard num not integer")); - } else { - if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting shardNumString to int")); - } - } - if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "realm num not integer")); - } else { - if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting realmNumString to int")); - } - } - if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "num not integer")); - } else { - if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting num to int")); - } - } - if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "private key not hex")); - } - if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "public key not hex")); - } - if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Network Type", "not integer")); - } else { - if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting network type to int")); - } - if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { - addError(new Error("Network Type", "invalid value")); - } - } - - if(0 == errorCount()) { - - auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + // collect + auto auto_renew_account_string = form.get("account-auto-renew-account", "0"); + auto auto_renew_period_string = form.get("account-auto-renew-period", "604800"); + auto account_initial_balance_string = form.get("account-initial-balance", "0"); - private_key = DataTypeConverter::hexToBin(privateKeyString); - public_key = DataTypeConverter::hexToBin(publicKeyString); - - - KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); - - if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); - if(!crypto_key->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving crypto key in DB")); - } + if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew account id not an integer")); } else { - printf("crypto key found in db\n"); - } - if(0 == errorCount()) { - - if(hedera_id->isExistInDB()) { - auto hedera_account = controller::HederaAccount::load(hedera_id); - if(hedera_account.isNull()) { - addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); - } else { - addError(new Error("Hedera Account", "Account already exist (same account id")); - } - - } else { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); - } + if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew account id to int")); } } - mm->releaseMemory(private_key); - mm->releaseMemory(public_key); - } + if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew period not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew period to int")); + } + } + + if(!sm->isValid(account_initial_balance_string, VALIDATE_ONLY_DECIMAL)) { + addError(new Error("Account", "initial balance not an decimal")); + } else { + if(DataTypeConverter::strToDouble(account_initial_balance_string, initial_balance) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Double convert error", "Error converting initial balance to double")); + } + } + if(0 == errorCount()) + { + } + + } else { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); + } + if(0 == errorCount()) { + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); + } + } } if(!query_hedera_account.isNull()) { getErrors(query_hedera_account); @@ -262,7 +305,15 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << "\n"; +#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -280,7 +331,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); @@ -288,59 +339,63 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(hedera_account_model->getUserId() == user->getModel()->getID()) { changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); } + auto isEncrypted = (*it)->getCryptoKey()->getModel()->isEncrypted(); //printf("change encryption: %s\n", changeEncryption.data()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 266 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    "; -#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - responseStream << ( (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" ); + responseStream << "\t\t\t\t\t
    "; +#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( isEncrypted ? "Ja": "Nein" ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" if(changeEncryption != "") { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 279 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; - responseStream << "\t

    Einen neuen Account anlegen

    \n"; + responseStream << "\t

    Ein existierenden Account eintragen

    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -356,25 +411,75 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t

    Ein neuen Account anlegen

    \n"; + responseStream << "\t\t

    Bei Hedera einen neuen Account anlegen und zum Start Hashbars von einem existierenden Account überweisen.

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t
    \n"; responseStream << "
    \n"; // begin include footer.cpsp responseStream << "
    \n"; @@ -400,5 +505,18 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << ""; // end include footer.cpsp responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; if (_compressResponse) _gzipStream.close(); } diff --git a/src/cpp/SingletonManager/HederaTaskManager.cpp b/src/cpp/SingletonManager/HederaTaskManager.cpp new file mode 100644 index 000000000..f54ca58f3 --- /dev/null +++ b/src/cpp/SingletonManager/HederaTaskManager.cpp @@ -0,0 +1,17 @@ +#include "HederaTaskManager.h" + +HederaTaskManager* HederaTaskManager::getInstance() +{ + static HederaTaskManager one; + return &one; +} + +HederaTaskManager::HederaTaskManager() +{ + +} + +HederaTaskManager::~HederaTaskManager() +{ + +} \ No newline at end of file diff --git a/src/cpp/SingletonManager/HederaTaskManager.h b/src/cpp/SingletonManager/HederaTaskManager.h new file mode 100644 index 000000000..361ace551 --- /dev/null +++ b/src/cpp/SingletonManager/HederaTaskManager.h @@ -0,0 +1,23 @@ +#ifndef __GRADIDO_LOGIN_SINGLETON_MANAGER_HEDERA_TASK_MANAGER_H +#define __GRADIDO_LOGIN_SINGLETON_MANAGER_HEDERA_TASK_MANAGER_H + +/*! + * @author: Dario Rekowski + * + * @date: 11.09.2020 + * + * @brief: Manage Hedera Task, waiting on Consensus for Hedera Transactions + * +*/ + +class HederaTaskManager +{ +public: + ~HederaTaskManager(); + + static HederaTaskManager* getInstance(); +protected: + HederaTaskManager(); +}; + +#endif //__GRADIDO_LOGIN_SINGLETON_MANAGER_HEDERA_TASK_MANAGER_H \ No newline at end of file diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index bbeaf9052..4e99b85e4 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -48,6 +48,7 @@ bool SessionManager::init() case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; + case VALIDATE_ONLY_DECIMAL: mValidations[i] = new Poco::RegularExpression("^[0-9]*(\.|,)[0-9]*$"); break; case VALIDATE_ONLY_HEX: mValidations[i] = new Poco::RegularExpression("^(0x)?[a-fA-F0-9]*$"); break; //case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}$"); break; case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\/?"); break; diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index 99ef301f0..4596d2064 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -29,6 +29,7 @@ enum SessionValidationTypes { VALIDATE_PASSPHRASE, VALIDATE_HAS_NUMBER, VALIDATE_ONLY_INTEGER, + VALIDATE_ONLY_DECIMAL, VALIDATE_ONLY_HEX, VALIDATE_ONLY_URL, VALIDATE_HAS_SPECIAL_CHARACTER, diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 22a82c929..25f3c7245 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -3,8 +3,13 @@ #include "NodeServer.h" #include "CryptoKey.h" #include "../model/hedera/Query.h" +//#include "../model/hedera/Tr" #include "HederaRequest.h" +#include "../SingletonManager/ErrorManager.h" + +using namespace Poco::Data::Keywords; + namespace controller { HederaAccount::HederaAccount(model::table::HederaAccount* dbModel) @@ -54,6 +59,51 @@ namespace controller { return nullptr; } + Poco::AutoPtr HederaAccount::pick(model::table::HederaNetworkType networkType, bool encrypted/* = false*/) + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); + + Poco::Tuple result_tuple; + int crypto_key_type = encrypted ? model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED : model::table::KEY_TYPE_ED25519_HEDERA_CLEAR; + //id, user_id, account_hedera_id, account_key_id, balance, network_type, updated + + select << "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num FROM hedera_accounts as account " + << "JOIN hedera_ids as i ON(i.id = account.account_hedera_id) " + << "JOIN crypto_keys as k ON(k.id = account.account_key_id) " + << "WHERE account.network_type = ? AND k.crypto_key_type_id = ? ORDER BY RAND() LIMIT 1 ", + into(result_tuple), use(networkType), use(crypto_key_type); + + try { + select.executeAsync(); + select.wait(); + if (1 == select.rowsExtracted()) { + auto db = new model::table::HederaAccount( + result_tuple.get<1>(), result_tuple.get<2>(), result_tuple.get<3>(), + result_tuple.get<4>(), networkType + ); + db->setID(result_tuple.get<0>()); + Poco::AutoPtr hedera_account(new HederaAccount(db)); + auto hedera_id_db = new model::table::HederaId(result_tuple.get<5>(), result_tuple.get<6>(), result_tuple.get<7>()); + Poco::AutoPtr hedera_id(new HederaId(hedera_id_db)); + hedera_account->setHederaId(hedera_id); + return hedera_account; + } + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + static const char* function_name = "HederaAccount::pick"; + em->addError(new ParamError(function_name, "mysql error: ", ex.displayText())); + em->addError(new ParamError(function_name, "network type: ", networkType)); + em->addError(new ParamError(function_name, "encrypted: ", (int)encrypted)); + em->sendErrorsAsEmail(); + } + + return nullptr; + + } + std::vector> HederaAccount::listAll() { auto db = new model::table::HederaAccount(); @@ -140,11 +190,27 @@ namespace controller { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } - getErrors(&request); + if (0 == errorCount() && 0 == request.errorCount()) { + return true; + } + getErrors(&request); return false; } + bool HederaAccount::hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance) + { + auto account_model = getModel(); + auto new_key_pair = KeyPairHedera::create(); + auto transaction_body = createTransactionBody(); + //CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod); + model::hedera::CryptoCreateTransaction create_transaction(new_key_pair->getPublicKey(), initialBalance, autoRenewPeriodSeconds); + transaction_body->setCryptoCreate(create_transaction); + + + return false; + } + bool HederaAccount::changeEncryption(Poco::AutoPtr user) { assert(!user.isNull() && user->getModel()); @@ -166,6 +232,13 @@ namespace controller { } + std::unique_ptr HederaAccount::createTransactionBody() + { + auto account_model = getModel(); + auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); + return std::make_unique(mHederaID, hedera_node); + } + std::string HederaAccount::toShortSelectOptionName() { diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 77f34aa87..882800713 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -5,6 +5,8 @@ #include "User.h" #include "../model/table/HederaAccount.h" +#include "../model/hedera/TransactionBody.h" + #include "Poco/SharedPtr.h" #include "TableControllerBase.h" @@ -21,6 +23,8 @@ namespace controller { static std::vector> load(const std::string& fieldName, int fieldValue); static Poco::AutoPtr load(Poco::AutoPtr hederaId); static std::vector> listAll(); + //! \brief for picking a account for paying transaction, mostly consensusSendMessage + static Poco::AutoPtr pick(model::table::HederaNetworkType networkType, bool encrypted = false); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } @@ -35,9 +39,14 @@ namespace controller { Poco::AutoPtr getCryptoKey() const; bool hederaAccountGetBalance(Poco::AutoPtr user); + bool hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance); bool changeEncryption(Poco::AutoPtr user); + //! \brief create Transaction body with this hedera account as operator + std::unique_ptr createTransactionBody(); + protected: + HederaAccount(model::table::HederaAccount* dbModel); Poco::AutoPtr mHederaID; diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index de2cf1dfa..3b9627c8b 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -1,4 +1,7 @@ #include "HederaId.h" +#include "../SingletonManager/ErrorManager.h" + +using namespace Poco::Data::Keywords; namespace controller { @@ -30,6 +33,42 @@ namespace controller { return nullptr; } + Poco::AutoPtr HederaId::find(int groupId, model::table::HederaNetworkType networkType) + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + model::table::HederaIdTuple result_tuple; + + Poco::Data::Statement select(session); + select << "SELECT h.id, h.shardNum, h.realmNum, h.num FROM hedera_ids as h " + << "JOIN hedera_topics as topic ON(topic.topic_hedera_id = h.id) " + << "JOIN hedera_accounts as account ON(account.id = topic.auto_renew_account_hedera_id) " + << "WHERE topic.group_id = ? AND account.network_type = ?" + , into(result_tuple), use(groupId), use(networkType); + + try { + /*select.executeAsync(); + select.wait(); + auto result_count = select.rowsExtracted();*/ + auto result_count = select.execute(); + if (1 == result_count) { + return new HederaId(new model::table::HederaId(result_tuple)); + } + else { + printf("[HederaId::find] result_count other as expected: %d\n", result_count); + } + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + static const char* function_name = "HederaId::find"; + em->addError(new ParamError(function_name, "mysql error: ", ex.displayText())); + em->addError(new ParamError(function_name, "group id: ", groupId)); + em->addError(new ParamError(function_name, "network type: ", (int)networkType)); + em->sendErrorsAsEmail(); + } + return nullptr; + } + void HederaId::copyToProtoAccountId(proto::AccountID* protoAccountId) const { auto model = getModel(); @@ -38,6 +77,14 @@ namespace controller { protoAccountId->set_accountnum(model->getNum()); } + void HederaId::copyToProtoTopicId(proto::TopicID* protoTopicId) const + { + auto model = getModel(); + protoTopicId->set_shardnum(model->getShardNum()); + protoTopicId->set_realmnum(model->getRealmNum()); + protoTopicId->set_topicnum(model->getNum()); + } + bool HederaId::isExistInDB() { auto model = getModel(); diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index 1cf967927..0bfc1f691 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -2,6 +2,7 @@ #define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE #include "../model/table/HederaId.h" +#include "../model/table/HederaAccount.h" #include "Poco/SharedPtr.h" @@ -10,8 +11,10 @@ #include "../proto/hedera/BasicTypes.pb.h" namespace controller { + class HederaAccount; class HederaId : public TableControllerBase { + friend HederaAccount; public: ~HederaId(); @@ -19,6 +22,8 @@ namespace controller { static Poco::AutoPtr create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); static Poco::AutoPtr load(int id); + //! \return hedera topic id for group and network type (should exist only one) + static Poco::AutoPtr find(int groupId, model::table::HederaNetworkType networkType); bool isExistInDB(); @@ -28,6 +33,7 @@ namespace controller { inline const model::table::HederaId* getModel() const { return _getModel(); } void copyToProtoAccountId(proto::AccountID* protoAccountId) const; + void copyToProtoTopicId(proto::TopicID* protoTopicId) const; protected: diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 64998fa6a..7ddb95800 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -1,5 +1,6 @@ #include "HederaRequest.h" #include "../proto/hedera/CryptoService.grpc.pb.h" +#include "../proto/hedera/ConsensusService.grpc.pb.h" #include "../lib/DataTypeConverter.h" @@ -71,6 +72,33 @@ HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transacti return HEDERA_REQUEST_RETURN_OK; } +HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, HederaTask* task) +{ + assert(transaction && task); + auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials()); + + grpc::ClientContext context; + std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + + std::chrono::milliseconds(5000); + context.set_deadline(deadline); + auto transaction_type = transaction->getType(); + if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type) { + auto stub = proto::ConsensusService::NewStub(channel); + + auto status = stub->submitMessage(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse()); + if (status.ok()) { + return HEDERA_REQUEST_RETURN_OK; + } + else { + addError(new ParamError("Hedera Request", "consensus service submit message error message:", status.error_message())); + addError(new ParamError("Hedera Request", "details: ", status.error_details())); + return HEDERA_REQUEST_RETURN_ERROR; + } + } + addError(new ParamError("Hedera Request", "not implemnetet or unknown transaction type", transaction_type)); + return HEDERA_REQUEST_UNKNOWN_TRANSACTION; +} + #include "Poco/JSON/Object.h" #include "../lib/JsonRequest.h" diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 34bd304a1..56adf3c79 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -14,12 +14,16 @@ #include "../model/hedera/Query.h" #include "../model/hedera/Transaction.h" #include "../model/hedera/Response.h" +#include "../model/hedera/TransactionResponse.h" +#include "../tasks/HederaTask.h" enum HederaRequestReturn { HEDERA_REQUEST_RETURN_OK, HEDERA_REQUEST_RETURN_PARSE_ERROR, HEDERA_REQUEST_RETURN_ERROR, + HEDERA_REQUEST_UNKNOWN_TRANSACTION, + HEDERA_REQUEST_UNKNOWN_QUERY, HEDERA_REQUEST_CONNECT_ERROR }; @@ -32,6 +36,9 @@ public: HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response); + //! + //! \param task goes into HederaTaskManager and will be run after transaction + HederaRequestReturn request(model::hedera::Transaction* transaction, HederaTask* task); //! for testing, didn't work server say invalid json :/ HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp index 31d18a94c..d852b57e7 100644 --- a/src/cpp/controller/HederaTopic.cpp +++ b/src/cpp/controller/HederaTopic.cpp @@ -19,6 +19,8 @@ namespace controller { return Poco::AutoPtr(hedera_topic); } + + Poco::UInt64 HederaTopic::hederaCreateTopic() { return 0; diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h index 4c2ebefb6..c7b169b4b 100644 --- a/src/cpp/controller/HederaTopic.h +++ b/src/cpp/controller/HederaTopic.h @@ -13,6 +13,7 @@ #include "TableControllerBase.h" #include "../model/table/HederaTopic.h" + namespace controller { class HederaTopic : public TableControllerBase { @@ -27,6 +28,7 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + inline Poco::AutoPtr getModel() { return _getModel(); } @@ -36,4 +38,4 @@ namespace controller { }; } -#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H \ No newline at end of file +#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index 72e6aceb8..0e84b4be4 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -55,6 +55,34 @@ namespace DataTypeConverter } } + NumberParseState strToDouble(const std::string& input, double& result) + { + auto comma_position = input.find(','); + std::string input_filtered = input; + if (comma_position > 0 && comma_position != input.npos) { + input_filtered = input_filtered.replace(comma_position, 0, 1, '.'); + } + try { + result = stod(input_filtered); + return NUMBER_PARSE_OKAY; + } + catch (const std::invalid_argument& ia) + { + printf("[strToDouble] exception: invalid argument: %s\n", ia.what()); + return NUMBER_PARSE_INVALID_ARGUMENT; + } + catch (const std::out_of_range& oor) + { + printf("[strToDouble] exception: out or range: %s\n", oor.what()); + return NUMBER_PARSE_OUT_OF_RANGE; + } + catch (const std::logic_error & ler) + { + printf("[strToDouble] exception: logical error: %s\n", ler.what()); + return NUMBER_PARSE_LOGIC_ERROR; + } + } + const char* numberParseStateToString(NumberParseState state) { switch (state) { diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index d970d697d..933fdfb74 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -23,6 +23,7 @@ namespace DataTypeConverter { NumberParseState strToInt(const std::string& input, int& result); NumberParseState strToInt(const std::string& input, unsigned long long& result); + NumberParseState strToDouble(const std::string& input, double& result); MemoryBin* hexToBin(const std::string& hexString); MemoryBin* base64ToBin(const std::string& base64String); diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.cpp b/src/cpp/model/hedera/ConsensusSubmitMessage.cpp index e69de29bb..18da97c73 100644 --- a/src/cpp/model/hedera/ConsensusSubmitMessage.cpp +++ b/src/cpp/model/hedera/ConsensusSubmitMessage.cpp @@ -0,0 +1,42 @@ +#include "ConsensusSubmitMessage.h" + +namespace model { + namespace hedera { + ConsensusSubmitMessage::ConsensusSubmitMessage(Poco::AutoPtr topicID) + : mConsensusMessageBody(nullptr) + { + mConsensusMessageBody = new proto::ConsensusSubmitMessageTransactionBody; + topicID->copyToProtoTopicId(mConsensusMessageBody->mutable_topicid()); + } + + ConsensusSubmitMessage::~ConsensusSubmitMessage() + { + if (mConsensusMessageBody) { + delete mConsensusMessageBody; + mConsensusMessageBody = nullptr; + } + } + + bool ConsensusSubmitMessage::validate() + { + // TODO: unpack gradido transaction and make simple validation check + assert(mConsensusMessageBody); + if (0 == mConsensusMessageBody->message().size()) { + printf("[ConsensusSubmitMessage::validate] empty message\n"); + return false; + } + if (!mConsensusMessageBody->has_topicid()) { + printf("[ConsensusSubmitMessage::validate] empty topic id\n"); + return false; + } + + return true; + } + + void ConsensusSubmitMessage::setMessage(std::string byteString) + { + assert(mConsensusMessageBody); + mConsensusMessageBody->set_message(byteString); + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.h b/src/cpp/model/hedera/ConsensusSubmitMessage.h index e69de29bb..d08b72279 100644 --- a/src/cpp/model/hedera/ConsensusSubmitMessage.h +++ b/src/cpp/model/hedera/ConsensusSubmitMessage.h @@ -0,0 +1,32 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H + +#include "../../proto/hedera/ConsensusSubmitMessage.pb.h" +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + + class ConsensusSubmitMessage + { + public: + ConsensusSubmitMessage(Poco::AutoPtr topicID); + ~ConsensusSubmitMessage(); + + inline proto::ConsensusSubmitMessageTransactionBody* getProtoTransactionBody() { return mConsensusMessageBody; } + inline void resetPointer() { mConsensusMessageBody = nullptr; } + void setMessage(std::string byteString); + inline void setMessage(const MemoryBin* message) { setMessage(std::string((const char*)message->data(), message->size())); } + + bool validate(); + + + + protected: + proto::ConsensusSubmitMessageTransactionBody* mConsensusMessageBody; + + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.cpp b/src/cpp/model/hedera/CryptoCreateTransaction.cpp index 696a8d6e7..1c5d58e11 100644 --- a/src/cpp/model/hedera/CryptoCreateTransaction.cpp +++ b/src/cpp/model/hedera/CryptoCreateTransaction.cpp @@ -3,14 +3,32 @@ namespace model { namespace hedera { - CryptoCreateTransaction::CryptoCreateTransaction() + CryptoCreateTransaction::CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod) { + mCryptoCreateBody = new proto::CryptoCreateTransactionBody; + // public key + auto key = mCryptoCreateBody->mutable_key(); + auto public_key = new std::string((const char*)publicKey, KeyPairHedera::getPublicKeySize()); + key->set_allocated_ed25519(public_key); + + mCryptoCreateBody->set_initialbalance(initialBalance); + + auto auto_renew_period = mCryptoCreateBody->mutable_autorenewperiod(); + auto_renew_period->set_seconds(autoRenewPeriod); + } CryptoCreateTransaction::~CryptoCreateTransaction() { - + if (mCryptoCreateBody) { + delete mCryptoCreateBody; + mCryptoCreateBody = nullptr; + } } + bool CryptoCreateTransaction::validate() + { + return true; + } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.h b/src/cpp/model/hedera/CryptoCreateTransaction.h index e1425ebf5..7182f3506 100644 --- a/src/cpp/model/hedera/CryptoCreateTransaction.h +++ b/src/cpp/model/hedera/CryptoCreateTransaction.h @@ -3,15 +3,23 @@ #include "../../proto/hedera/CryptoCreate.pb.h" +#include "../Crypto/KeyPairHedera.h" + namespace model { namespace hedera { class CryptoCreateTransaction { public: - CryptoCreateTransaction(); + //! \param publicKey newly created public key from ed25519 public-private key pair for hedera + CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod); ~CryptoCreateTransaction(); + proto::CryptoCreateTransactionBody* getProtoTransactionBody() { return mCryptoCreateBody; } + inline void resetPointer() { mCryptoCreateBody = nullptr; } + + bool validate(); + protected: proto::CryptoCreateTransactionBody* mCryptoCreateBody; }; diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.cpp b/src/cpp/model/hedera/CryptoTransferTransaction.cpp index 828a85645..171e239f4 100644 --- a/src/cpp/model/hedera/CryptoTransferTransaction.cpp +++ b/src/cpp/model/hedera/CryptoTransferTransaction.cpp @@ -43,11 +43,6 @@ namespace model { } return 0 == sum && transfers->accountamounts_size() > 0; } - - void CryptoTransferTransaction::resetPointer() - { - mCryptoTransfer = nullptr; - } } } diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.h b/src/cpp/model/hedera/CryptoTransferTransaction.h index 04aacafea..21d9bd3c3 100644 --- a/src/cpp/model/hedera/CryptoTransferTransaction.h +++ b/src/cpp/model/hedera/CryptoTransferTransaction.h @@ -26,7 +26,7 @@ namespace model { bool validate(); // set pointer to zero, after hand over pointer to transaction body - void resetPointer(); + inline void resetPointer() { mCryptoTransfer = nullptr; } inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; } diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index 4699e71ea..ab786e44f 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -18,6 +18,8 @@ namespace model { bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) { + mType = transactionBody->getType(); + auto mm = MemoryManager::getInstance(); mConnection = transactionBody->getConnection(); auto transaction_body_proto = transactionBody->getProtoTransactionBody(); @@ -40,5 +42,32 @@ namespace model { mm->releaseMemory(sign); return true; } + + bool Transaction::sign(std::unique_ptr keyPairHedera, std::unique_ptr transactionBody) + { + mType = transactionBody->getType(); + + auto mm = MemoryManager::getInstance(); + mConnection = transactionBody->getConnection(); + auto transaction_body_proto = transactionBody->getProtoTransactionBody(); + auto body_bytes = transaction_body_proto->SerializeAsString(); + mTransaction->set_bodybytes(body_bytes.data(), body_bytes.size()); + auto signature_map = mTransaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_map->add_sigpair(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + return true; + } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index d5e9434bd..fe1bfed51 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -23,14 +23,17 @@ namespace model { ~Transaction(); bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); + bool sign(std::unique_ptr keyPairHedera, std::unique_ptr transactionBody); inline proto::Transaction* getTransaction() { return mTransaction; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } void resetPointer() { mTransaction = nullptr; } + inline TransactionBodyType getType() const { return mType; } protected: proto::Transaction* mTransaction; controller::NodeServerConnection mConnection; + TransactionBodyType mType; }; } } diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index f215ada23..ea44915a8 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -3,7 +3,7 @@ namespace model { namespace hedera { TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) - : mConnection(connection) + : mConnection(connection), mHasBody(false) { connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); auto transaction_id = mTransactionBody.mutable_transactionid(); @@ -22,9 +22,15 @@ namespace model { bool TransactionBody::setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction) { + if (mHasBody) { + printf("[TransactionBody::setCryptoTransfer] has already a body\n"); + return false; + } if (cryptoTransferTransaction.validate()) { mTransactionBody.set_allocated_cryptotransfer(cryptoTransferTransaction.getProtoTransactionBody()); cryptoTransferTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CRYPTO_TRANSFER; return true; } return false; @@ -32,9 +38,47 @@ namespace model { bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction) { + if (mHasBody) { + printf("[TransactionBody::setCreateTopic] has already a body\n"); + return false; + } if (consensusCreateTopicTransaction.validate()) { mTransactionBody.set_allocated_consensuscreatetopic(consensusCreateTopicTransaction.getProtoTransactionBody()); consensusCreateTopicTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CONSENSUS_CREATE_TOPIC; + return true; + } + return false; + } + + bool TransactionBody::setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction) + { + if (mHasBody) { + printf("[TransactionBody::setCryptoCreate] has already a body\n"); + return false; + } + if (cryptoCreateTransaction.validate()) { + mTransactionBody.set_allocated_cryptocreateaccount(cryptoCreateTransaction.getProtoTransactionBody()); + cryptoCreateTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CRYPTO_CREATE; + return true; + } + return false; + } + + bool TransactionBody::setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction) + { + if (mHasBody) { + printf("[TransactionBody::setConsensusSubmitMessage] has already a body\n"); + return false; + } + if (consensusSubmitMessageTransaction.validate()) { + mTransactionBody.set_allocated_consensussubmitmessage(consensusSubmitMessageTransaction.getProtoTransactionBody()); + consensusSubmitMessageTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CONSENSUS_SUBMIT_MESSAGE; return true; } return false; diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 7be8d2105..9a5406af7 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -13,12 +13,23 @@ #include "../../controller/NodeServer.h" #include "CryptoTransferTransaction.h" +#include "CryptoCreateTransaction.h" #include "ConsensusCreateTopic.h" +#include "ConsensusSubmitMessage.h" #include "../../proto/hedera/TransactionBody.pb.h" namespace model { namespace hedera { + + enum TransactionBodyType + { + TRANSACTION_CRYPTO_TRANSFER, + TRANSACTION_CRYPTO_CREATE, + TRANSACTION_CONSENSUS_CREATE_TOPIC, + TRANSACTION_CONSENSUS_SUBMIT_MESSAGE + }; + class TransactionBody { public: @@ -29,17 +40,22 @@ namespace model { void setFee(Poco::UInt64 fee); bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + bool setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction); bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction); + bool setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction); //bool inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } inline controller::NodeServerConnection getConnection() const { return mConnection; } + inline TransactionBodyType getType() const { return mType; } protected: void updateTimestamp(); proto::TransactionBody mTransactionBody; controller::NodeServerConnection mConnection; + bool mHasBody; + TransactionBodyType mType; }; } } diff --git a/src/cpp/model/hedera/TransactionResponse.cpp b/src/cpp/model/hedera/TransactionResponse.cpp new file mode 100644 index 000000000..2e9a66ea1 --- /dev/null +++ b/src/cpp/model/hedera/TransactionResponse.cpp @@ -0,0 +1,18 @@ +#include "TransactionResponse.h" + +namespace model { + namespace hedera { + + TransactionResponse::TransactionResponse() + { + + } + + TransactionResponse::~TransactionResponse() + { + + } + + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionResponse.h b/src/cpp/model/hedera/TransactionResponse.h new file mode 100644 index 000000000..325cbe73f --- /dev/null +++ b/src/cpp/model/hedera/TransactionResponse.h @@ -0,0 +1,30 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H + +#include "../../proto/hedera/TransactionResponse.pb.h" +#include "Poco/Types.h" + +namespace model { + namespace hedera { + + class TransactionResponse + { + public: + TransactionResponse(); + ~TransactionResponse(); + + inline proto::ResponseCodeEnum getPrecheckCode() const { return mProtoResponse.nodetransactionprecheckcode();} + inline std::string getPrecheckCodeString() const { return proto::ResponseCodeEnum_Name(mProtoResponse.nodetransactionprecheckcode()); } + inline Poco::UInt64 getCost() const { return mProtoResponse.cost(); } + + proto::TransactionResponse* getProtoResponse() { return &mProtoResponse; } + protected: + proto::TransactionResponse mProtoResponse; + + }; + } +} + + + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index d6ceb8cb7..fce86a541 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -16,6 +16,13 @@ namespace model { } + HederaId::HederaId(const HederaIdTuple& tuple) + : ModelBase(tuple.get<0>()), + mShardNum(tuple.get<1>()), mRealmNum(tuple.get<2>()), mNum(tuple.get<3>()) + { + + } + HederaId::~HederaId() { diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index 9dc2029bc..bed00168f 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -7,11 +7,14 @@ namespace model { namespace table { + typedef Poco::Tuple HederaIdTuple; + class HederaId : public ModelBase { public: HederaId(); HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); + HederaId(const HederaIdTuple& tuple); ~HederaId(); // generic db operations @@ -25,7 +28,6 @@ namespace model { inline Poco::UInt64 getRealmNum() const { return mRealmNum; } inline Poco::UInt64 getNum() const { return mNum; } - protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); diff --git a/src/cpp/tasks/HederaTask.cpp b/src/cpp/tasks/HederaTask.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/tasks/HederaTask.h b/src/cpp/tasks/HederaTask.h new file mode 100644 index 000000000..0c22da226 --- /dev/null +++ b/src/cpp/tasks/HederaTask.h @@ -0,0 +1,15 @@ +#ifndef __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H +#define __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H + +#include "../model/hedera/TransactionResponse.h" + +class HederaTask +{ +public: + inline model::hedera::TransactionResponse* getTransactionResponse() { return &mTransactionResponse; } + +protected: + model::hedera::TransactionResponse mTransactionResponse; +}; + +#endif //__GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H \ No newline at end of file diff --git a/src/cpp/tasks/SigningTransaction.cpp b/src/cpp/tasks/SigningTransaction.cpp index df317a270..ab1196a54 100644 --- a/src/cpp/tasks/SigningTransaction.cpp +++ b/src/cpp/tasks/SigningTransaction.cpp @@ -20,6 +20,12 @@ #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPResponse.h" +// stuff for hedera transaction +#include "../controller/HederaAccount.h" +#include "../controller/HederaRequest.h" +#include "../model/hedera/TransactionBody.h" +#include "../model/hedera/Transaction.h" + SigningTransaction::SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser) : mProcessingeTransaction(processingeTransaction), mNewUser(newUser) { @@ -152,6 +158,41 @@ int SigningTransaction::run() { return -6; } + auto network_type = model::table::HEDERA_TESTNET; + auto topic_id = controller::HederaId::find(1, network_type); + auto hedera_operator_account = controller::HederaAccount::pick(network_type, false); + + if (!topic_id.isNull() && !hedera_operator_account.isNull()) { + auto crypto_key = hedera_operator_account->getCryptoKey(); + if (!crypto_key.isNull()) { + model::hedera::ConsensusSubmitMessage consensus_submit_message(topic_id); + consensus_submit_message.setMessage(finalTransactionBin); + auto hedera_transaction_body = hedera_operator_account->createTransactionBody(); + hedera_transaction_body->setConsensusSubmitMessage(consensus_submit_message); + model::hedera::Transaction hedera_transaction; + hedera_transaction.sign(crypto_key->getKeyPair(), std::move(hedera_transaction_body)); + + HederaRequest hedera_request; + HederaTask hedera_task;// placeholder + if (HEDERA_REQUEST_RETURN_OK != hedera_request.request(&hedera_transaction, &hedera_task)) { + addError(new Error("SigningTransaction", "error send transaction to hedera")); + getErrors(&hedera_request); + sendErrorsAsEmail(); + } + else { + auto hedera_precheck_code_string = hedera_task.getTransactionResponse()->getPrecheckCodeString(); + printf("hedera response: %s\n", hedera_precheck_code_string.data()); + } + //model::hedera::TransactionBody hedera_transaction_body() + } + else { + printf("[SigningTransaction] crypto key not found\n"); + } + } + else { + printf("[SigningTransaction] hedera topic id or operator account not found\n"); + } + // finale to base64 auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); auto finalBase64Bin = mm->getFreeMemory(finalBase64Size); diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index b55701b1b..d3d68b82c 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -24,6 +24,9 @@ auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + int auto_renew_period = 604800; // 7 Tage + int auto_renew_account = 0; + double initial_balance = 0.0; Profiler hedera_time; std::string hedera_time_string; @@ -59,8 +62,11 @@ if(action == "updateBalance") { hedera_time.reset(); - query_hedera_account->hederaAccountGetBalance(user); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + if(query_hedera_account->hederaAccountGetBalance(user)) { + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } else { + addError(new ParamError("Hedera", "crypto get balance failed in ", hedera_time.string())); + } } else if(action == "changeEncryption") { @@ -69,113 +75,150 @@ } } } - else if(!form.empty()) // add + else if(!form.empty()) // add or create { - // collect - auto shardNumString = form.get("account-shard-num", "0"); - auto realmNumString = form.get("account-realm-num", "0"); - auto numString = form.get("account-num", "0"); - auto privateKeyString = form.get("account-private-key", ""); - auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); - auto publicKeyString = form.get("account-public-key", ""); - auto networkTypeString = form.get("account-network-type", "0"); + auto creationButton = form.get("create",""); + if(creationButton != "") { - //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); - - int shardNum = 0; - int realmNum = 0; - int num = 0; - int networkType = 0; - - MemoryBin* private_key = nullptr; - MemoryBin* public_key = nullptr; - - // validate - if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "shard num not integer")); - } else { - if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting shardNumString to int")); - } - } - if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "realm num not integer")); - } else { - if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting realmNumString to int")); - } - } - if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "num not integer")); - } else { - if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting num to int")); - } - } - if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "private key not hex")); - } - if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "public key not hex")); - } - if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Network Type", "not integer")); - } else { - if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting network type to int")); - } - if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { - addError(new Error("Network Type", "invalid value")); - } - } - - if(0 == errorCount()) { - - auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + // collect + auto auto_renew_account_string = form.get("account-auto-renew-account", "0"); + auto auto_renew_period_string = form.get("account-auto-renew-period", "604800"); + auto account_initial_balance_string = form.get("account-initial-balance", "0"); - private_key = DataTypeConverter::hexToBin(privateKeyString); - public_key = DataTypeConverter::hexToBin(publicKeyString); - - - KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); - - if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); - if(!crypto_key->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving crypto key in DB")); - } + if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew account id not an integer")); } else { - printf("crypto key found in db\n"); - } - if(0 == errorCount()) { - - if(hedera_id->isExistInDB()) { - auto hedera_account = controller::HederaAccount::load(hedera_id); - if(hedera_account.isNull()) { - addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); - } else { - addError(new Error("Hedera Account", "Account already exist (same account id")); - } - - } else { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); - } + if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew account id to int")); } } - mm->releaseMemory(private_key); - mm->releaseMemory(public_key); - } + if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew period not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew period to int")); + } + } + + if(!sm->isValid(account_initial_balance_string, VALIDATE_ONLY_DECIMAL)) { + addError(new Error("Account", "initial balance not an decimal")); + } else { + if(DataTypeConverter::strToDouble(account_initial_balance_string, initial_balance) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Double convert error", "Error converting initial balance to double")); + } + } + if(0 == errorCount()) + { + } + + } else { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); + } + if(0 == errorCount()) { + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); + } + } } if(!query_hedera_account.isNull()) { getErrors(query_hedera_account); @@ -184,6 +227,14 @@ auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); %><%@ include file="header_large.cpsp" %> + <%= getErrorsHtml() %>
    @@ -207,13 +258,14 @@ if(hedera_account_model->getUserId() == user->getModel()->getID()) { changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); } + auto isEncrypted = (*it)->getCryptoKey()->getModel()->isEncrypted(); //printf("change encryption: %s\n", changeEncryption.data()); %>
    <%= (*it)->getHederaId()->getModel()->toString() %>
    <%= hedera_account_model->getBalanceDouble() %> hbar
    <%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
    -
    <%= (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" %>
    +
    "><%= isEncrypted ? "Ja": "Nein" %>
    <%= hedera_account_model->getUpdatedString() %>
    -

    Einen neuen Account anlegen

    +

    Ein existierenden Account eintragen

    @@ -248,8 +300,39 @@ <% } %> - "> + "> +
    +
    +
    +

    Ein neuen Account anlegen

    +

    Bei Hedera einen neuen Account anlegen und zum Start Hashbars von einem existierenden Account überweisen.

    +
    +
    +
    + + + +
    + + + ">
    <%@ include file="footer.cpsp" %> + + From 4cd082bc944f86254d0333db7104ec3e4cbf29eb Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 15 Sep 2020 14:34:13 +0200 Subject: [PATCH 029/195] add tests for hedera account and hedera id for faster fixing mysql error --- CMakeLists.txt | 3 +- src/cpp/test/controller/TestHederaAccount.cpp | 14 ++ src/cpp/test/controller/TestHederaAccount.h | 13 ++ src/cpp/test/controller/TestHederaId.cpp | 14 ++ src/cpp/test/controller/TestHederaId.h | 13 ++ src/cpp/test/controller/TestHederaTopic.cpp | 0 src/cpp/test/controller/TestHederaTopic.h | 0 src/cpp/test/main.cpp | 196 ++++++++++++++++++ 8 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 src/cpp/test/controller/TestHederaAccount.cpp create mode 100644 src/cpp/test/controller/TestHederaAccount.h create mode 100644 src/cpp/test/controller/TestHederaId.cpp create mode 100644 src/cpp/test/controller/TestHederaId.h create mode 100644 src/cpp/test/controller/TestHederaTopic.cpp create mode 100644 src/cpp/test/controller/TestHederaTopic.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fc2eb1771..c8cbe2e74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,11 +213,12 @@ enable_testing() add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) 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 absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf -pthread) endif(WIN32) diff --git a/src/cpp/test/controller/TestHederaAccount.cpp b/src/cpp/test/controller/TestHederaAccount.cpp new file mode 100644 index 000000000..2300dc60b --- /dev/null +++ b/src/cpp/test/controller/TestHederaAccount.cpp @@ -0,0 +1,14 @@ +#include "TestHederaAccount.h" +#include "../SingletonManager/ConnectionManager.h" +namespace controller { + + void TestHederaAccount::SetUp() + { + + } + + TEST_F(TestHederaAccount, TestPick) { + auto hedera_account = controller::HederaAccount::pick(model::table::HEDERA_TESTNET, false); + EXPECT_FALSE(hedera_account.isNull()); + } +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaAccount.h b/src/cpp/test/controller/TestHederaAccount.h new file mode 100644 index 000000000..7e8e7843a --- /dev/null +++ b/src/cpp/test/controller/TestHederaAccount.h @@ -0,0 +1,13 @@ +#include "gtest/gtest.h" + +#include "../controller/HederaAccount.h" + + +namespace controller { + + class TestHederaAccount : public ::testing::Test { + protected: + void SetUp() override; + }; + +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaId.cpp b/src/cpp/test/controller/TestHederaId.cpp new file mode 100644 index 000000000..ad17e0933 --- /dev/null +++ b/src/cpp/test/controller/TestHederaId.cpp @@ -0,0 +1,14 @@ +#include "TestHederaId.h" +#include "../SingletonManager/ConnectionManager.h" +namespace controller { + + void TestHederaId::SetUp() + { + + } + + TEST_F(TestHederaId, TestFindTopicId) { + auto hedera_topic_id = controller::HederaId::find(1, model::table::HEDERA_TESTNET); + EXPECT_FALSE(hedera_topic_id.isNull()); + } +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaId.h b/src/cpp/test/controller/TestHederaId.h new file mode 100644 index 000000000..b6e4b574e --- /dev/null +++ b/src/cpp/test/controller/TestHederaId.h @@ -0,0 +1,13 @@ +#include "gtest/gtest.h" + +#include "../controller/HederaId.h" + + +namespace controller { + + class TestHederaId : public ::testing::Test { + protected: + void SetUp() override; + }; + +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaTopic.cpp b/src/cpp/test/controller/TestHederaTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/test/controller/TestHederaTopic.h b/src/cpp/test/controller/TestHederaTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/test/main.cpp b/src/cpp/test/main.cpp index 5fcab4163..62482c664 100644 --- a/src/cpp/test/main.cpp +++ b/src/cpp/test/main.cpp @@ -8,6 +8,8 @@ #include "../SingletonManager/ConnectionManager.h" +#include "../lib/Profiler.h" + std::list gTests; @@ -20,6 +22,21 @@ void fillTests() // gTests.push_back(new LoginTest()); } +void runMysql(std::string sqlQuery) +{ + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement mysqlStatement(session); + mysqlStatement << sqlQuery; + + try { + mysqlStatement.execute(true); + } + catch (Poco::Exception& ex) { + printf("exception in runMysql: %s\n", ex.displayText().data()); + } +} + int load() { // init server config, init seed array @@ -54,7 +71,186 @@ int load() { //printf("try connect php server mysql \n"); conn->setConnectionsFromConfig(*test_config, CONNECTION_MYSQL_PHP_SERVER); + Profiler timeUsed; + // clean up and fill db + std::string tables[] = { + "hedera_accounts", + "hedera_ids", + "crypto_keys", + "hedera_topics", + "groups", + "node_servers", + "users" + }; + for (int i = 0; i < 7; i++) { + runMysql("TRUNCATE " + tables[i]); + runMysql("ALTER TABLE " + tables[i] + " AUTO_INCREMENT = 1"); + } + + std::stringstream ss; + ss << "INSERT INTO `users` (`id`, `email`, `first_name`, `last_name`, `password`, `pubkey`, `privkey`, `created`, `email_checked`, `passphrase_shown`, `language`, `disabled`) VALUES " + << "(1, 'einhorn_silas@ist-allein.info', 'DDD', 'Schultz', 13134558453895551556, 0x146d3fb9e88abc0fca0b0091c1ab1b32b399be037436f340befa8bf004461889, 0x0dcc08960f45f631fe23bc7ddee0724cedc9ec0c861ce30f5091d20ffd96062d08ca215726fb9bd64860c754772e945eea4cc872ed0a36c7b640e8b0bf7a873ec6765fa510711622341347ce2307b5ce, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(2, 'Dario.Rekowski@buerotiger.de', 'Darios', 'Bruder', 12910944485867375321, 0x952e215a21d4376b4ac252c4bf41e156e1498e1b6b8ccf2a6826d96712f4f461, 0x4d40bf0860655f728312140dc3741e897bc2d13d00ea80a63e2961046a5a7bd8315397dfb488b89377087bc1a5f4f3af8ffdcf203329ae23ba04be7d38ad3852699d90ff1fc00e5b1ca92b64cc59c01f, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(3, 'morgenstern175@es-ist-liebe.de', 'Dieter', 'Schultz', 13528673707291575501, 0xb539944bf6444a2bfc988244f0c0c9dc326452be9b8a2a43fcd90663719f4f6d, 0x5461fda60b719b65ba00bd6298e48410c4cbf0e89deb13cc784ba8978cf047454e8556ee3eddc8487ee835c33a83163bc8d8babbf2a5c431876bc0a0c114ff0a0d6b57baa12cf8f23c64fb642c862db5, '2020-02-20 16:05:45', 1, 0, 'de', 0), " + << "(4, 'spaceteam@gmx.de', 'Bernd', 'Hückstädt', 15522411320147607375, 0x476b059744f08b0995522b484c90f8d2f47d9b59f4b3c96d9dc0ae6ab7b84979, 0x5277bf044cba4fec64e6f4d38da132755b029161231daefc9a7b4692ad37e05cdd88e0a2c2215baf854dd3a813578c214167af1113607e9f999ca848a7598ba5068e38f2a1afb097e4752a88024d79c8, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(5, 'em741@gmx.de', 'Thomas', 'Markuk', 7022671043835614958, 0xb1584e169d60a7e771d3a348235dfd7b5f9e8235fcc26090761a0264b0daa6ff, 0xb46fb7110bf91e28f367aa80f84d1bbd639b6f689f4b0aa28c0f71529232df9bf9ee0fb02fa4c1b9f5a6799c82d119e5646f7231d011517379faaacf6513d973ac3043d4c786490ba62d56d75b86164d, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(6, 'coin-info12@gradido.net', 'coin-info12', 'Test', 1548398919826089202, 0x4046ae49c1b620f2a321aba0c874fa2bc7ba844ab808bb0eeb18a908d468db14, 0x9522657ecd7456eedf86d065aa087ba7a94a8961a8e4950d044136155d38fe0840f2c0a2876ce055b3eaa6e9ab95c5feba89e535e0434fb2648d94d6e6ec68211aa2ea9e42d1ccd40b6b3c31e41f848e, '2020-02-20 16:05:47', 1, 0, 'de', 0), " + << "(7, 'info@einhornimmond.de', 'Alex', 'Wesper', 5822761891727948301, 0xb13ede3402abb8f29722b14fec0a2006ae7a3a51fb677cd6a2bbd797ac6905a5, 0x6aa39d7670c64a31639c7d89b874ad929b2eaeb2e5992dbad71b6cea700bf9e3c6cf866d0f0fdc22b44a0ebf51a860799e880ef86266199931dd0a301e5552db44b9b7fa99ed5945652bc7b31eff767c, '2020-02-20 16:05:47', 1, 0, 'de', 0); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `description`) VALUES " + << "(1, 'gdd1', 'Gradido1', 'gdd1.gradido.com', 'Der erste offizielle Gradido Server (zum Testen)'); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES " + << "(1, 2, 15, 1, 1000000000000, 1, '2020-09-03 11:13:52'), " + << "(2, 2, 17, 2, 22787166159, 0, '2020-09-03 11:13:56'); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES " + << "(1, 0, 0, 3), " + << "(2, 0, 0, 4)," + << "(3, 0, 0, 5)," + << "(4, 0, 0, 6)," + << "(6, 0, 0, 3)," + << "(10, 0, 0, 7)," + << "(11, 0, 0, 8)," + << "(12, 0, 0, 9)," + << "(13, 0, 0, 10)," + << "(14, 0, 0, 12)," + << "(15, 0, 0, 3327)," + << "(16, 0, 0, 3323)," + << "(17, 0, 0, 8707)," + << "(18, 0, 0, 39446);"; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `crypto_keys` (`id`, `private_key`, `public_key`, `crypto_key_type_id`) VALUES " + << "(1, 0xd2d4735174e6d2577573a0ec2767fba6511b1e37cd1cd98674912797fd37e12373d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 0x73d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 3), " + << "(2, 0xf1c3285be6ef869a2a8deef6caee56a5a7c2660e2bce24f39e420dd8d42fe8894bd027b2799e46dc7111a4fdd0eac3848054331f844a358de15c5b0ed3eb1740fab13ecb5a271d480e040c9266bcd584, 0xd6f6d29fb277f86ac7c3098dc799028974223e8dce6b1dd57b03940bf35fae7f, 1); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `updated`) VALUES " + << "(1, 18, 'from Pauls created with his python script', 1, 0, 1, NULL, NULL, '1999-12-31 23:00:00', 0, '2020-09-14 18:29:04'); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES " + << "(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'), " + << "(2, 'http://1.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00'), " + << "(3, 'http://2.testnet.hedera.com', 50211, 0, 4, 3, '2000-01-01 00:00:00'), " + << "(4, 'http://3.testnet.hedera.com', 50211, 0, 4, 4, '2000-01-01 00:00:00'), " + << "(5, 'http://35.237.200.180', 50211, 0, 3, 6, '2000-01-01 00:00:00'), " + << "(6, 'http://35.186.191.247', 50211, 0, 3, 2, '2000-01-01 00:00:00'), " + << "(7, 'http://35.192.2.25', 50211, 0, 3, 3, '2000-01-01 00:00:00'), " + << "(8, 'http://35.199.161.108', 50211, 0, 3, 4, '2000-01-01 00:00:00'), " + << "(9, 'http://35.203.82.240', 50211, 0, 3, 10, '2000-01-01 00:00:00'), " + << "(10, 'http://35.236.5.219', 50211, 0, 3, 11, '2000-01-01 00:00:00'), " + << "(11, 'http://35.197.192.225', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(12, 'http://35.242.233.154', 50211, 0, 3, 13, '2000-01-01 00:00:00'), " + << "(13, 'http://35.240.118.96', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(14, 'http://35.204.86.32', 50211, 0, 3, 14, '2000-01-01 00:00:00'), " + << "(15, 'https://gradido.dario-rekowski.de/', 443, 1, 2, 0, '2000-01-01 00:00:00'), " + << "(16, 'http://192.168.178.232', 8340, 1, 1, 0, '2000-01-01 00:00:00'); "; + runMysql(ss.str()); + + printf("init db in : %s\n", timeUsed.string().data()); + + /*mysqlStatement + << "TRUNCATE hedera_accounts; " + << "ALTER TABLE hedera_accounts AUTO_INCREMENT = 1; " + << "TRUNCATE hedera_ids; " + << "ALTER TABLE hedera_ids AUTO_INCREMENT = 1; " + << "TRUNCATE crypto_keys; " + << "ALTER TABLE crypto_keys AUTO_INCREMENT = 1; " + << "TRUNCATE hedera_topics; " + << "ALTER TABLE hedera_topics AUTO_INCREMENT = 1; " + << "TRUNCATE groups; " + << "ALTER TABLE groups AUTO_INCREMENT = 1; " + << "TRUNCATE node_servers; " + << "ALTER TABLE node_servers AUTO_INCREMENT = 1; " + << "TRUNCATE users; " + << "ALTER TABLE users AUTO_INCREMENT = 1; " + ; + + try { + mysqlStatement.execute(true); + } + catch (Poco::Exception& ex) { + printf("exception by cleaning up db: %s\n", ex.displayText().data()); + } + mysqlStatement.reset(session); + mysqlStatement + << "INSERT INTO `users` (`id`, `email`, `first_name`, `last_name`, `password`, `pubkey`, `privkey`, `created`, `email_checked`, `passphrase_shown`, `language`, `disabled`) VALUES " + << "(1, 'einhorn_silas@ist-allein.info', 'DDD', 'Schultz', 13134558453895551556, 0x146d3fb9e88abc0fca0b0091c1ab1b32b399be037436f340befa8bf004461889, 0x0dcc08960f45f631fe23bc7ddee0724cedc9ec0c861ce30f5091d20ffd96062d08ca215726fb9bd64860c754772e945eea4cc872ed0a36c7b640e8b0bf7a873ec6765fa510711622341347ce2307b5ce, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(2, 'Dario.Rekowski@buerotiger.de', 'Darios', 'Bruder', 12910944485867375321, 0x952e215a21d4376b4ac252c4bf41e156e1498e1b6b8ccf2a6826d96712f4f461, 0x4d40bf0860655f728312140dc3741e897bc2d13d00ea80a63e2961046a5a7bd8315397dfb488b89377087bc1a5f4f3af8ffdcf203329ae23ba04be7d38ad3852699d90ff1fc00e5b1ca92b64cc59c01f, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(3, 'morgenstern175@es-ist-liebe.de', 'Dieter', 'Schultz', 13528673707291575501, 0xb539944bf6444a2bfc988244f0c0c9dc326452be9b8a2a43fcd90663719f4f6d, 0x5461fda60b719b65ba00bd6298e48410c4cbf0e89deb13cc784ba8978cf047454e8556ee3eddc8487ee835c33a83163bc8d8babbf2a5c431876bc0a0c114ff0a0d6b57baa12cf8f23c64fb642c862db5, '2020-02-20 16:05:45', 1, 0, 'de', 0), " + << "(4, 'spaceteam@gmx.de', 'Bernd', 'Hückstädt', 15522411320147607375, 0x476b059744f08b0995522b484c90f8d2f47d9b59f4b3c96d9dc0ae6ab7b84979, 0x5277bf044cba4fec64e6f4d38da132755b029161231daefc9a7b4692ad37e05cdd88e0a2c2215baf854dd3a813578c214167af1113607e9f999ca848a7598ba5068e38f2a1afb097e4752a88024d79c8, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(5, 'em741@gmx.de', 'Thomas', 'Markuk', 7022671043835614958, 0xb1584e169d60a7e771d3a348235dfd7b5f9e8235fcc26090761a0264b0daa6ff, 0xb46fb7110bf91e28f367aa80f84d1bbd639b6f689f4b0aa28c0f71529232df9bf9ee0fb02fa4c1b9f5a6799c82d119e5646f7231d011517379faaacf6513d973ac3043d4c786490ba62d56d75b86164d, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(6, 'coin-info12@gradido.net', 'coin-info12', 'Test', 1548398919826089202, 0x4046ae49c1b620f2a321aba0c874fa2bc7ba844ab808bb0eeb18a908d468db14, 0x9522657ecd7456eedf86d065aa087ba7a94a8961a8e4950d044136155d38fe0840f2c0a2876ce055b3eaa6e9ab95c5feba89e535e0434fb2648d94d6e6ec68211aa2ea9e42d1ccd40b6b3c31e41f848e, '2020-02-20 16:05:47', 1, 0, 'de', 0), " + << "(7, 'info@einhornimmond.de', 'Alex', 'Wesper', 5822761891727948301, 0xb13ede3402abb8f29722b14fec0a2006ae7a3a51fb677cd6a2bbd797ac6905a5, 0x6aa39d7670c64a31639c7d89b874ad929b2eaeb2e5992dbad71b6cea700bf9e3c6cf866d0f0fdc22b44a0ebf51a860799e880ef86266199931dd0a301e5552db44b9b7fa99ed5945652bc7b31eff767c, '2020-02-20 16:05:47', 1, 0, 'de', 0); " + + << "INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `description`) VALUES " + << "(1, 'gdd1', 'Gradido1', 'gdd1.gradido.com', 'Der erste offizielle Gradido Server (zum Testen)'); " + + << "INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES " + << "(1, 2, 15, 1, 1000000000000, 1, '2020-09-03 11:13:52'), " + << "(2, 2, 17, 2, 22787166159, 0, '2020-09-03 11:13:56'); " + + << "INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES " + << "(1, 0, 0, 3), " + << "(2, 0, 0, 4)," + << "(3, 0, 0, 5)," + << "(4, 0, 0, 6)," + << "(6, 0, 0, 3)," + << "(10, 0, 0, 7)," + << "(11, 0, 0, 8)," + << "(12, 0, 0, 9)," + << "(13, 0, 0, 10)," + << "(14, 0, 0, 12)," + << "(15, 0, 0, 3327)," + << "(16, 0, 0, 3323)," + << "(17, 0, 0, 8707)," + << "(18, 0, 0, 39446);" + + << "INSERT INTO `crypto_keys` (`id`, `private_key`, `public_key`, `crypto_key_type_id`) VALUES " + << "(1, 0xd2d4735174e6d2577573a0ec2767fba6511b1e37cd1cd98674912797fd37e12373d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 0x73d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 3), " + << "(2, 0xf1c3285be6ef869a2a8deef6caee56a5a7c2660e2bce24f39e420dd8d42fe8894bd027b2799e46dc7111a4fdd0eac3848054331f844a358de15c5b0ed3eb1740fab13ecb5a271d480e040c9266bcd584, 0xd6f6d29fb277f86ac7c3098dc799028974223e8dce6b1dd57b03940bf35fae7f, 1); " + + << "INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `updated`) VALUES " + << "(1, 18, 'from Pauls created with his python script', 1, 0, 1, NULL, NULL, '1999-12-31 23:00:00', 0, '2020-09-14 18:29:04'); " + + << "INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES " + << "(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'), " + << "(2, 'http://1.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00'), " + << "(3, 'http://2.testnet.hedera.com', 50211, 0, 4, 3, '2000-01-01 00:00:00'), " + << "(4, 'http://3.testnet.hedera.com', 50211, 0, 4, 4, '2000-01-01 00:00:00'), " + << "(5, 'http://35.237.200.180', 50211, 0, 3, 6, '2000-01-01 00:00:00'), " + << "(6, 'http://35.186.191.247', 50211, 0, 3, 2, '2000-01-01 00:00:00'), " + << "(7, 'http://35.192.2.25', 50211, 0, 3, 3, '2000-01-01 00:00:00'), " + << "(8, 'http://35.199.161.108', 50211, 0, 3, 4, '2000-01-01 00:00:00'), " + << "(9, 'http://35.203.82.240', 50211, 0, 3, 10, '2000-01-01 00:00:00'), " + << "(10, 'http://35.236.5.219', 50211, 0, 3, 11, '2000-01-01 00:00:00'), " + << "(11, 'http://35.197.192.225', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(12, 'http://35.242.233.154', 50211, 0, 3, 13, '2000-01-01 00:00:00'), " + << "(13, 'http://35.240.118.96', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(14, 'http://35.204.86.32', 50211, 0, 3, 14, '2000-01-01 00:00:00'), " + << "(15, 'https://gradido.dario-rekowski.de/', 443, 1, 2, 0, '2000-01-01 00:00:00'), " + << "(16, 'http://192.168.178.232', 8340, 1, 1, 0, '2000-01-01 00:00:00'); " + ; + + try { + mysqlStatement.execute(); + } + catch (Poco::Exception& ex) { + printf("exception by init db with data: %s\n", ex.displayText().data()); + } + */ fillTests(); for (std::list::iterator it = gTests.begin(); it != gTests.end(); it++) { From 01bf8a3870111cca21af86101925d310e6eb974e Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 15 Sep 2020 14:35:12 +0200 Subject: [PATCH 030/195] fix mysql error, cast enum to int before using in poco data use --- src/cpp/controller/HederaAccount.cpp | 21 +++++++++++++++------ src/cpp/controller/HederaId.cpp | 10 +++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 25f3c7245..4a1c45c7c 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -67,18 +67,23 @@ namespace controller { Poco::Tuple result_tuple; int crypto_key_type = encrypted ? model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED : model::table::KEY_TYPE_ED25519_HEDERA_CLEAR; - //id, user_id, account_hedera_id, account_key_id, balance, network_type, updated + int network_type_int = (int)networkType; - select << "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num FROM hedera_accounts as account " - << "JOIN hedera_ids as i ON(i.id = account.account_hedera_id) " + select + << "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num " + << "FROM hedera_accounts as account " + << "JOIN hedera_ids as i ON(i.id = account_hedera_id) " << "JOIN crypto_keys as k ON(k.id = account.account_key_id) " - << "WHERE account.network_type = ? AND k.crypto_key_type_id = ? ORDER BY RAND() LIMIT 1 ", - into(result_tuple), use(networkType), use(crypto_key_type); + << "WHERE account.network_type = ? " + << "AND k.crypto_key_type_id = ? " + << "ORDER BY RAND() LIMIT 1 " + , into(result_tuple), use(network_type_int) , use(crypto_key_type); try { select.executeAsync(); select.wait(); - if (1 == select.rowsExtracted()) { + auto result_count = select.rowsExtracted(); + if (1 == result_count) { auto db = new model::table::HederaAccount( result_tuple.get<1>(), result_tuple.get<2>(), result_tuple.get<3>(), result_tuple.get<4>(), networkType @@ -90,10 +95,14 @@ namespace controller { hedera_account->setHederaId(hedera_id); return hedera_account; } + else if(result_count > 1) { + printf("[HederaAccount::pick] extracted rows not like expected\n"); + } } catch (Poco::Exception& ex) { auto em = ErrorManager::getInstance(); static const char* function_name = "HederaAccount::pick"; + printf("exception: %s\n", ex.displayText().data()); em->addError(new ParamError(function_name, "mysql error: ", ex.displayText())); em->addError(new ParamError(function_name, "network type: ", networkType)); em->addError(new ParamError(function_name, "encrypted: ", (int)encrypted)); diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index 3b9627c8b..9e39cd84b 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -38,23 +38,23 @@ namespace controller { auto cm = ConnectionManager::getInstance(); auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); model::table::HederaIdTuple result_tuple; + int network_type_int = (int)networkType; Poco::Data::Statement select(session); select << "SELECT h.id, h.shardNum, h.realmNum, h.num FROM hedera_ids as h " << "JOIN hedera_topics as topic ON(topic.topic_hedera_id = h.id) " << "JOIN hedera_accounts as account ON(account.id = topic.auto_renew_account_hedera_id) " << "WHERE topic.group_id = ? AND account.network_type = ?" - , into(result_tuple), use(groupId), use(networkType); + , into(result_tuple), use(groupId), use(network_type_int); try { - /*select.executeAsync(); + select.executeAsync(); select.wait(); - auto result_count = select.rowsExtracted();*/ - auto result_count = select.execute(); + auto result_count = select.rowsExtracted(); if (1 == result_count) { return new HederaId(new model::table::HederaId(result_tuple)); } - else { + else if(result_count > 1) { printf("[HederaId::find] result_count other as expected: %d\n", result_count); } } From 8c4a354d92801b5c37d3d31a69886769ddd07c42 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Sep 2020 13:22:17 +0200 Subject: [PATCH 031/195] work on hedera task for hedera transactions async --- src/cpp/model/hedera/Transaction.cpp | 2 + src/cpp/model/hedera/Transaction.h | 2 + src/cpp/model/hedera/TransactionReceipt.cpp | 16 ++++++++ src/cpp/model/hedera/TransactionReceipt.h | 23 +++++++++++ src/cpp/model/hedera/TransactionRecord.cpp | 0 src/cpp/model/hedera/TransactionRecord.h | 0 src/cpp/tasks/HederaTask.cpp | 45 +++++++++++++++++++++ src/cpp/tasks/HederaTask.h | 36 ++++++++++++++++- src/cpp/tasks/SigningTransaction.cpp | 6 ++- 9 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/cpp/model/hedera/TransactionReceipt.cpp create mode 100644 src/cpp/model/hedera/TransactionReceipt.h create mode 100644 src/cpp/model/hedera/TransactionRecord.cpp create mode 100644 src/cpp/model/hedera/TransactionRecord.h diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index ab786e44f..779488630 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -58,6 +58,8 @@ namespace model { auto signature_pair = signature_pairs->Mutable(0); auto public_key = keyPairHedera->getPublicKey(); + mTransactionId = transactionBody->getProtoTransactionBody()->transactionid(); + auto sign = keyPairHedera->sign(body_bytes); if (!sign) { printf("[Query::sign] error signing message\n"); diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index fe1bfed51..5938a0f1e 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -29,11 +29,13 @@ namespace model { inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } void resetPointer() { mTransaction = nullptr; } inline TransactionBodyType getType() const { return mType; } + inline proto::TransactionID getTransactionId() const { return mTransactionId; } protected: proto::Transaction* mTransaction; controller::NodeServerConnection mConnection; TransactionBodyType mType; + proto::TransactionID mTransactionId; }; } } diff --git a/src/cpp/model/hedera/TransactionReceipt.cpp b/src/cpp/model/hedera/TransactionReceipt.cpp new file mode 100644 index 000000000..46966814d --- /dev/null +++ b/src/cpp/model/hedera/TransactionReceipt.cpp @@ -0,0 +1,16 @@ +#include "TransactionReceipt.h" + +namespace model { + namespace hedera { + + TransactionReceipt::TransactionReceipt() + { + + } + + TransactionReceipt::~TransactionReceipt() + { + + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionReceipt.h b/src/cpp/model/hedera/TransactionReceipt.h new file mode 100644 index 000000000..ed1036857 --- /dev/null +++ b/src/cpp/model/hedera/TransactionReceipt.h @@ -0,0 +1,23 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H + +#include "../proto/hedera/TransactionReceipt.pb.h" + +namespace model { + namespace hedera { + class TransactionReceipt + { + public: + TransactionReceipt(); + ~TransactionReceipt(); + + inline proto::TransactionReceipt* getProto() { return &mProtoReceipt; } + + protected: + proto::TransactionReceipt mProtoReceipt; + + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionRecord.cpp b/src/cpp/model/hedera/TransactionRecord.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/TransactionRecord.h b/src/cpp/model/hedera/TransactionRecord.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/tasks/HederaTask.cpp b/src/cpp/tasks/HederaTask.cpp index e69de29bb..9cd152d27 100644 --- a/src/cpp/tasks/HederaTask.cpp +++ b/src/cpp/tasks/HederaTask.cpp @@ -0,0 +1,45 @@ +#include "HederaTask.h" +#include "../lib/DataTypeConverter.h" + +#include "../proto/hedera/TransactionGetReceipt.pb.h" + +HederaTask::HederaTask() + : mTransactionReceipt(nullptr) +{ + +} + +HederaTask::~HederaTask() +{ + if (mTransactionReceipt) { + delete mTransactionReceipt; + mTransactionReceipt = nullptr; + } +} + +bool HederaTask::isTimeout() +{ + std::shared_lock _lock(mWorkingMutex); + auto valid_start = mTransactionID.transactionvalidstart(); + auto poco_timestamp = DataTypeConverter::convertFromProtoTimestamp(valid_start); + auto poco_duration = DataTypeConverter::convertFromProtoDuration(mValidDuration); + return (poco_timestamp + poco_duration) > Poco::Timestamp(); +} + +void HederaTask::setTransactionReceipt(model::hedera::TransactionReceipt* transactionReceipt) +{ + assert(transactionReceipt); + + std::unique_lock _lock(mWorkingMutex); + if (mTransactionReceipt) { + printf("[HederaTask::setTransactionReceipt] warning, receipt already set\n"); + delete mTransactionReceipt; + } + mTransactionReceipt = transactionReceipt; +} + +bool HederaTask::tryQueryReceipt() +{ + proto::TransactionGetReceiptQuery get_receipt_query; + return true; +} \ No newline at end of file diff --git a/src/cpp/tasks/HederaTask.h b/src/cpp/tasks/HederaTask.h index 0c22da226..3576ca7b6 100644 --- a/src/cpp/tasks/HederaTask.h +++ b/src/cpp/tasks/HederaTask.h @@ -2,14 +2,48 @@ #define __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H #include "../model/hedera/TransactionResponse.h" +#include "../model/hedera/TransactionReceipt.h" +#include "../proto/hedera/BasicTypes.pb.h" +#include "../proto/hedera/Duration.pb.h" + +#include "Poco/Timestamp.h" + +#include class HederaTask { public: - inline model::hedera::TransactionResponse* getTransactionResponse() { return &mTransactionResponse; } + + HederaTask(); + ~HederaTask(); + + inline model::hedera::TransactionResponse* getTransactionResponse() { std::shared_lock _lock(mWorkingMutex); return &mTransactionResponse; } + inline void setTransactionId(const proto::TransactionID& transactionId) { std::unique_lock _lock(mWorkingMutex); mTransactionID = transactionId; } + inline void setValidDuration(const proto::Duration& validDuration) { std::unique_lock _lock(mWorkingMutex); mValidDuration = validDuration; } + //! \param transactionReceipt take ownership and call delete if done + void setTransactionReceipt(model::hedera::TransactionReceipt* transactionReceipt); + + inline const proto::TransactionID& getTransactionId() const { std::shared_lock _lock(mWorkingMutex); return mTransactionID; } + inline const proto::Duration& getDuration() const { std::shared_lock _lock(mWorkingMutex); return mValidDuration; } + inline const model::hedera::TransactionReceipt* getTransactionReceipt() const{ std::shared_lock _lock(mWorkingMutex); return mTransactionReceipt; } + + //! \ brief return true if transactionValidStart + validDuration > now + bool isTimeout(); + + bool tryQueryReceipt(); + protected: model::hedera::TransactionResponse mTransactionResponse; + model::hedera::TransactionReceipt* mTransactionReceipt; + + proto::TransactionID mTransactionID; + proto::Duration mValidDuration; + + // last time checked if transaction receipt is available + Poco::Timestamp mLastCheck; + + mutable std::shared_mutex mWorkingMutex; }; #endif //__GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H \ No newline at end of file diff --git a/src/cpp/tasks/SigningTransaction.cpp b/src/cpp/tasks/SigningTransaction.cpp index ab1196a54..50e5953b3 100644 --- a/src/cpp/tasks/SigningTransaction.cpp +++ b/src/cpp/tasks/SigningTransaction.cpp @@ -1,5 +1,8 @@ +#include + #include "SigningTransaction.h" + #include #include "../SingletonManager/ErrorManager.h" @@ -181,7 +184,8 @@ int SigningTransaction::run() { } else { auto hedera_precheck_code_string = hedera_task.getTransactionResponse()->getPrecheckCodeString(); - printf("hedera response: %s\n", hedera_precheck_code_string.data()); + auto cost = hedera_task.getTransactionResponse()->getCost(); + printf("hedera response: %s, cost: %" PRIu64 "\n", hedera_precheck_code_string.data(), cost); } //model::hedera::TransactionBody hedera_transaction_body() } From 48e732b897f352dc4c85e1a353565c06b0e861f9 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Sep 2020 13:25:15 +0200 Subject: [PATCH 032/195] prepare for hedera get topic info query --- .../hedera/ConsensusGetTopicInfoResponse.cpp | 15 ++++++++++ .../hedera/ConsensusGetTopicInfoResponse.h | 22 ++++++++++++++ src/cpp/model/hedera/Query.cpp | 25 ++++++++++++++++ src/cpp/model/hedera/Query.h | 2 ++ src/cpp/model/hedera/QueryHeader.cpp | 16 ++++++++++ src/cpp/model/hedera/QueryHeader.h | 25 ++++++++++++++++ src/cpp/model/hedera/Response.cpp | 15 ++++++++++ src/cpp/model/hedera/Response.h | 4 +++ src/cpp/model/hedera/TransactionBody.cpp | 30 ++++++++++++++++++- src/cpp/model/hedera/TransactionBody.h | 1 + 10 files changed, 154 insertions(+), 1 deletion(-) diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp index e69de29bb..f99d82934 100644 --- a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp +++ b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp @@ -0,0 +1,15 @@ +#include "ConsensusGetTopicInfoResponse.h" + +namespace model { + namespace hedera { + ConsensusGetTopicInfoResponse::ConsensusGetTopicInfoResponse() + { + + } + + ConsensusGetTopicInfoResponse::~ConsensusGetTopicInfoResponse() + { + + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h index e69de29bb..63b837101 100644 --- a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h +++ b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h @@ -0,0 +1,22 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H + +#include "../proto/hedera/ConsensusGetTopicInfo.pb.h" + +namespace model +{ + namespace hedera + { + class ConsensusGetTopicInfoResponse + { + public: + ConsensusGetTopicInfoResponse(); + ~ConsensusGetTopicInfoResponse(); + + protected: + proto::ConsensusGetTopicInfoResponse mProto; + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index 11a8eb735..c478a96ff 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -48,6 +48,29 @@ namespace model { return query; } + Query* Query::getTopicInfo(Poco::AutoPtr topicId, Poco::AutoPtr payerAccountId, const controller::NodeServerConnection& connection) + { + assert(!topicId.isNull() && topicId->getModel()); + assert(!payerAccountId.isNull() && payerAccountId->getModel()); + + auto query = new Query; + auto get_topic_info = query->mQueryProto.mutable_consensusgettopicinfo(); + topicId->copyToProtoTopicId(get_topic_info->mutable_topicid()); + + auto query_header = get_topic_info->mutable_header(); + query_header->set_responsetype(proto::ANSWER_ONLY); + + query->mTransactionBody = new TransactionBody(payerAccountId, connection); + CryptoTransferTransaction crypto_transaction; + // 0.002809 Hashbars + // fee from https://www.hedera.com/fees + crypto_transaction.addSender(payerAccountId, -2809); + crypto_transaction.addReceiver(connection.hederaId, 2809); + query->mTransactionBody->setCryptoTransfer(crypto_transaction); + + return query; + } + bool Query::sign(std::unique_ptr keyPairHedera) { Transaction transaction; @@ -73,5 +96,7 @@ namespace model { auto query_header = get_account_balance->mutable_header(); return query_header->responsetype(); } + + } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index 376528314..5c633e66c 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -22,10 +22,12 @@ namespace model { public: ~Query(); static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); + static Query* getTopicInfo(Poco::AutoPtr topicId, Poco::AutoPtr payerAccountId, const controller::NodeServerConnection& connection); bool sign(std::unique_ptr keyPairHedera); void setResponseType(proto::ResponseType type); proto::ResponseType getResponseType(); + inline bool setTransactionFee(Poco::UInt64 fee) { return mTransactionBody->updateCryptoTransferAmount(fee);} inline const proto::Query* getProtoQuery() const { return &mQueryProto; } inline std::string getConnectionString() const { return mTransactionBody->getConnectionString(); } diff --git a/src/cpp/model/hedera/QueryHeader.cpp b/src/cpp/model/hedera/QueryHeader.cpp index e69de29bb..c622841ec 100644 --- a/src/cpp/model/hedera/QueryHeader.cpp +++ b/src/cpp/model/hedera/QueryHeader.cpp @@ -0,0 +1,16 @@ +#include "QueryHeader.h" + +namespace model { + namespace hedera { + QueryHeader::QueryHeader(Transaction* paymentTransaction) + { + mProtoQueryHeader.set_responsetype(proto::ANSWER_ONLY); + } + + QueryHeader::~QueryHeader() + { + + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/QueryHeader.h b/src/cpp/model/hedera/QueryHeader.h index e69de29bb..47261e24a 100644 --- a/src/cpp/model/hedera/QueryHeader.h +++ b/src/cpp/model/hedera/QueryHeader.h @@ -0,0 +1,25 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H + +#include "../proto/hedera/QueryHeader.pb.h" +#include "Transaction.h" + +namespace model { + namespace hedera { + class QueryHeader + { + public: + QueryHeader(Transaction* paymentTransaction); + ~QueryHeader(); + + void setResponseType(proto::ResponseType type) { mProtoQueryHeader.set_responsetype(type); }; + proto::ResponseType getResponseType() const { return mProtoQueryHeader.responsetype(); } + + protected: + proto::QueryHeader mProtoQueryHeader; + + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp index a39c5364e..d0a88ad94 100644 --- a/src/cpp/model/hedera/Response.cpp +++ b/src/cpp/model/hedera/Response.cpp @@ -20,6 +20,21 @@ namespace model { return 0; } + Poco::UInt64 Response::getQueryCost() + { + proto::ResponseHeader* response_header = nullptr; + if (mResponseProto.has_consensusgettopicinfo()) { + response_header = mResponseProto.mutable_consensusgettopicinfo()->mutable_header(); + } + else if (mResponseProto.has_cryptogetaccountbalance()) { + response_header = mResponseProto.mutable_cryptogetaccountbalance()->mutable_header(); + } + if (response_header) { + return response_header->cost(); + } + return 0; + } + proto::ResponseCodeEnum Response::getResponseCode() { if (isCryptoGetAccountBalanceResponse()) { diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h index 779f5e982..89599b8c4 100644 --- a/src/cpp/model/hedera/Response.h +++ b/src/cpp/model/hedera/Response.h @@ -11,6 +11,7 @@ */ #include "../../proto/hedera/Response.pb.h" +#include "ConsensusGetTopicInfoResponse.h" #include "Poco/Types.h" namespace model { @@ -23,9 +24,12 @@ namespace model { inline proto::Response* getResponsePtr() { return &mResponseProto; } Poco::UInt64 getAccountBalance(); + Poco::UInt64 getQueryCost(); proto::ResponseCodeEnum getResponseCode(); + inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); } + inline bool isConsensusGetTopicInfoResponse() { return mResponseProto.has_consensusgettopicinfo(); } protected: proto::Response mResponseProto; diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index ea44915a8..4ecae0fb9 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -8,7 +8,7 @@ namespace model { connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); auto transaction_id = mTransactionBody.mutable_transactionid(); operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid()); - mTransactionBody.set_transactionfee(10000); + mTransactionBody.set_transactionfee(1000000); auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration(); transaction_valid_duration->set_seconds(120); @@ -36,6 +36,34 @@ namespace model { return false; } + bool TransactionBody::updateCryptoTransferAmount(Poco::UInt64 newAmount) + { + assert(mHasBody); + + if (!mTransactionBody.has_cryptotransfer()) { + printf("[TransactionBody::updateCryptoTransferAmount] hasn't crypto transfer\n"); + return false; + } + + auto crypto_transfer = mTransactionBody.mutable_cryptotransfer(); + auto transfers = crypto_transfer->mutable_transfers(); + if (transfers->accountamounts_size() != 2) { + printf("[TransactionBody::updateCryptoTransferAmount] structure not like expected, transfers has %d accountamounts\n", transfers->accountamounts_size()); + return false; + } + proto::AccountAmount* account_amounts[] = { transfers->mutable_accountamounts(0), transfers->mutable_accountamounts(1) }; + for (int i = 0; i < 2; i++) { + if (account_amounts[i]->amount() > 0) { + account_amounts[i]->set_amount(newAmount); + } + else if (account_amounts[i]->amount() < 0) { + account_amounts[i]->set_amount(-newAmount); + } + } + return true; + + } + bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction) { if (mHasBody) { diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 9a5406af7..c05f419ff 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -40,6 +40,7 @@ namespace model { void setFee(Poco::UInt64 fee); bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + bool updateCryptoTransferAmount(Poco::UInt64 newAmount); bool setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction); bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction); bool setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction); From d9122ad0be4cc87670e0c571a8b3025ada3c5086 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Sep 2020 13:26:05 +0200 Subject: [PATCH 033/195] update Hedera Topics Page to show existing topics --- skeema/gradido_login/hedera_topics.sql | 4 +- .../HTTPInterface/AdminHederaAccountPage.cpp | 68 ++--- src/cpp/HTTPInterface/AdminTopicPage.cpp | 245 ++++++++++++++---- src/cpp/controller/HederaAccount.cpp | 24 +- src/cpp/controller/HederaAccount.h | 6 +- src/cpp/controller/HederaRequest.cpp | 38 ++- src/cpp/controller/HederaTopic.cpp | 34 ++- src/cpp/controller/HederaTopic.h | 9 +- src/cpp/lib/DataTypeConverter.cpp | 11 + src/cpp/lib/DataTypeConverter.h | 6 + src/cpp/model/table/HederaAccount.cpp | 20 +- src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaTopic.cpp | 37 ++- src/cpp/model/table/HederaTopic.h | 10 +- src/cpp/model/table/ModelBase.cpp | 24 ++ src/cpp/model/table/ModelBase.h | 26 +- src/cpsp/adminHederaAccount.cpsp | 18 +- src/cpsp/adminTopic.cpsp | 55 +++- 18 files changed, 500 insertions(+), 136 deletions(-) diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index b9adaefc2..8bf279f3b 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -7,9 +7,9 @@ CREATE TABLE `hedera_topics` ( `group_id` int unsigned NOT NULL, `admin_key_id` int unsigned DEFAULT NULL, `submit_key_id` int unsigned DEFAULT NULL, - `current_timeout` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', + `current_timeout` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00', `sequence_number` bigint unsigned DEFAULT '0', - `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `topic_hedera_id` (`topic_hedera_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 5ff4f7218..4bcf9b614 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -349,8 +349,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; #line 266 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - responseStream << ( hedera_account_model->getBalanceDouble() ); - responseStream << " hbar
    \n"; + responseStream << ( hedera_account_model->getBalanceString() ); + responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; #line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); @@ -366,27 +366,29 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request #line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - if(changeEncryption != "") { responseStream << "\n"; - responseStream << "\t\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << "\t\t\t\t\t\t\t\tChange Encryption\n"; + responseStream << "\t\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 278 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; + responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 279 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -395,7 +397,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -411,21 +413,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; @@ -436,46 +438,46 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\n"; @@ -506,7 +508,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request // end include footer.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\t\t\n"; responseStream << "\t "; -#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" +#line 222 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" } else if(state == PAGE_ASK_PASSPHRASE) { responseStream << "\n"; responseStream << "\t \n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "
    \n"; - responseStream << "\t

    Login Server in Entwicklung

    \n"; - responseStream << "\t

    Alpha "; -#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" - responseStream << ( ServerConfig::g_versionString ); - responseStream << "

    \n"; - responseStream << "
    \n"; - // end include header_old.cpsp - responseStream << "\n"; - responseStream << "
    \n"; - responseStream << "\t

    Einen neuen Account anlegen

    \n"; - responseStream << "\t"; -#line 45 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - responseStream << ( getErrorsHtml() ); - responseStream << "\n"; - responseStream << "\t"; -#line 46 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - if(!form.empty() && userReturned) { responseStream << "\n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t\tDeine Anmeldung wird verarbeitet und es wird dir eine E-Mail zugeschickt. \n"; - responseStream << "\t\t\t\tWenn sie da ist, befolge ihren Anweisungen. \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t"; -#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - } else { responseStream << "\n"; - responseStream << "\t
    \n"; - responseStream << "\t\t\n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\tAccount anlegen\n"; - responseStream << "\t\t\t

    Bitte gebe deine Daten um einen Account anzulegen

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\n"; - responseStream << "\t\t\n"; - responseStream << "\t
    \n"; - responseStream << "\t"; -#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - } responseStream << "\n"; - responseStream << "
    \n"; - // begin include footer.cpsp - responseStream << "
    \n"; - responseStream << "

    Copyright © Gradido 2020

    \n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << " "; -#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" - responseStream << ( mTimeProfiler.string() ); - responseStream << "\n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "

    Login Server in Entwicklung

    \n"; - responseStream << "

    Alpha "; -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" - responseStream << ( ServerConfig::g_versionString ); - responseStream << "

    \n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << ""; - // end include footer.cpsp - responseStream << "\n"; - if (_compressResponse) _gzipStream.close(); -} diff --git a/src/cpp/HTTPInterface/RegisterPage.h b/src/cpp/HTTPInterface/RegisterPage.h deleted file mode 100644 index 7dc16970a..000000000 --- a/src/cpp/HTTPInterface/RegisterPage.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef RegisterPage_INCLUDED -#define RegisterPage_INCLUDED - - -#include "Poco/Net/HTTPRequestHandler.h" - - -#include "PageRequestMessagedHandler.h" - - -class RegisterPage: public PageRequestMessagedHandler -{ -public: - void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); -}; - - -#endif // RegisterPage_INCLUDED diff --git a/src/cpp/HTTPInterface/SaveKeysPage.cpp b/src/cpp/HTTPInterface/SaveKeysPage.cpp index 12064f812..3d8d79b67 100644 --- a/src/cpp/HTTPInterface/SaveKeysPage.cpp +++ b/src/cpp/HTTPInterface/SaveKeysPage.cpp @@ -40,7 +40,8 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne const char* pageName = "Daten auf Server speichern?"; bool hasErrors = mSession->errorCount() > 0; // crypto key only in memory, if user has tipped in his passwort in this session - bool hasPassword = mSession->getUser()->hasCryptoKey(); + auto user = mSession->getNewUser(); + bool hasPassword = user->getModel()->hasPrivateKeyEncrypted(); PageState state = PAGE_ASK; auto uri_start = ServerConfig::g_php_serverPath;//request.serverParams().getServerName(); @@ -161,11 +162,11 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "
    \n"; responseStream << "\t

    Daten speichern

    \n"; responseStream << "\t"; -#line 75 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 76 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\t"; -#line 76 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 77 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" if(state == PAGE_ASK) { responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; @@ -180,7 +181,7 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t

    \n"; responseStream << "\t\t\t"; -#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" if(!hasPassword) { responseStream << "\n"; responseStream << "\t\t\t\t

    Ich brauche nochmal dein Passwort wenn du dich für ja entscheidest.

    \n"; responseStream << "\t\t\t\t

    \n"; @@ -188,7 +189,7 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t

    \n"; responseStream << "\t\t\t"; -#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 96 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    \n"; responseStream << "\t\t\t\t\n"; @@ -213,15 +214,15 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\n"; responseStream << "\t

    \n"; responseStream << "\t"; -#line 118 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 119 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } else if(state == PAGE_SHOW_PUBKEY) { responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t

    "; -#line 120 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( gettext("Daten gespeichert!") ); responseStream << "

    \n"; responseStream << "\t\t\t

    "; -#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 122 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( gettext("Deine Daten wurden verschlüsselt und gespeichert.") ); responseStream << "

    \n"; responseStream << "\t\t\t\n"; @@ -229,27 +230,27 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\t\n"; responseStream << "\t\t\tZurück zur Startseite\n"; responseStream << "\t\t
    \n"; responseStream << "\t"; -#line 130 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 131 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } else if(state == PAGE_ERROR) { responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t

    Ein Fehler trat auf, bitte versuche es erneut oder wende dich an den Server-Admin

    \n"; responseStream << "\t\t\t"; -#line 133 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 134 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( mSession->getSessionStateString() ); responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t"; -#line 135 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 136 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } responseStream << "\n"; responseStream << "
    \n"; // begin include footer.cpsp diff --git a/src/cpp/HTTPInterface/TranslatePassphrase.cpp b/src/cpp/HTTPInterface/TranslatePassphrase.cpp index 512383518..3b14f9a2c 100644 --- a/src/cpp/HTTPInterface/TranslatePassphrase.cpp +++ b/src/cpp/HTTPInterface/TranslatePassphrase.cpp @@ -7,7 +7,7 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" @@ -50,16 +50,17 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P { inputPassphrase = form.get("inputPassphrase", ""); - auto localPassphrase = KeyPair::filterPassphrase(inputPassphrase); + auto localPassphrase = Passphrase::filter(inputPassphrase); auto btnGenerate = form.get("btnGenerate", ""); if("" != btnGenerate) { - mSession->generatePassphrase(); - localPassphrase = mSession->getOldPassphrase(); + auto passphrase_gen = Passphrase::generate(wordSource); + + localPassphrase = passphrase_gen->getString(); inputPassphrase = localPassphrase; } - - if(localPassphrase != "" && !User::validatePassphrase(localPassphrase, &wordSource)) { + auto passphrase_object = Passphrase::create(localPassphrase, wordSource); + if(localPassphrase != "" && passphrase_object.isNull() || !passphrase_object->checkIfValid()) { addError(new Error( gettext("Fehler"), gettext("Diese Passphrase ist ungültig, bitte überprüfen oder neu generieren (lassen).") @@ -70,7 +71,8 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P } else { targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]; } - passphrase = KeyPair::passphraseTransform(localPassphrase, wordSource, targetSource); + auto transformed_passphrase_obj = passphrase_object->transform(targetSource); + passphrase = transformed_passphrase_obj->getString(); } @@ -197,7 +199,7 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t

    "; -#line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 61 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Passphrase umwandeln") ); responseStream << "

    \n"; responseStream << "
    \n"; @@ -208,57 +210,57 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t
    "; -#line 67 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 69 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Was zu tun ist:") ); responseStream << "
    \n"; responseStream << "\t\t

    "; -#line 68 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 70 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Kopiere/schreibe deine Passphrase in die Textbox und du bekommst sie in die jeweils andere Sprache umgewandelt.") ); responseStream << "

    \n"; responseStream << "\t\t

    "; -#line 69 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 71 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Du kannst mit beiden Varianten dein Konto wiederherstellen oder dein Passwort ändern.") ); responseStream << "

    \n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t \n"; responseStream << "\t\t "; -#line 78 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 80 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" if(model::table::ROLE_ADMIN == role) { responseStream << "\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t "; -#line 80 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 82 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t "; -#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 85 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" if(passphrase != "") { responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t
    Umgewandelte Passphrase:
    \n"; responseStream << "\t\t\t\t

    "; -#line 87 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( passphrase ); responseStream << "

    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t "; -#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 92 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" } responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; diff --git a/src/cpp/HTTPInterface/UserUpdateGroupPage.cpp b/src/cpp/HTTPInterface/UserUpdateGroupPage.cpp new file mode 100644 index 000000000..f41928116 --- /dev/null +++ b/src/cpp/HTTPInterface/UserUpdateGroupPage.cpp @@ -0,0 +1,209 @@ +#include "UserUpdateGroupPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + + +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" + +enum PageState { + PAGE_STATE_OVERVIEW, + PAGE_STATE_REQUEST_IS_RUNNING +}; + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +UserUpdateGroupPage::UserUpdateGroupPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void UserUpdateGroupPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 17 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + + const char* pageName = gettext("Gruppe wählen"); + auto user = mSession->getNewUser(); + auto sm = SessionManager::getInstance(); + PageState state = PAGE_STATE_OVERVIEW; + + if(!form.empty()) { + } + + auto groups = controller::Group::listAll(); + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t
    "; + // end include header_large.cpsp + responseStream << "\n"; +#line 30 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t"; +#line 32 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + if(PAGE_STATE_OVERVIEW == state ) { responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "

    "; +#line 34 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Gruppe wählen") ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "\t

    "; +#line 36 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Bitte wähle die Gruppe/Gemeinschaft aus, zu der du gehörst.") ); + responseStream << "

    \n"; + responseStream << "\t

    "; +#line 37 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Du bekommst eine Bestätigungsmail, nachdem dein Beitritt bestätigt wurde.") ); + responseStream << "

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t
    "; +#line 41 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Auswahl") ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t
    Name
    \n"; + responseStream << "\t\t\t\t
    Alias
    \n"; + responseStream << "\t\t\t\t
    Url
    \n"; + responseStream << "\t\t\t\t
    "; +#line 45 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Description") ); + responseStream << "
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 47 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t
    getID()); + responseStream << "\" />
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 51 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getName() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 52 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getAlias() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getUrl() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 54 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getDescription()); + responseStream << "
    \n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t"; +#line 60 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + } responseStream << "\n"; + responseStream << "
    \n"; + // begin include footer.cpsp + responseStream << "
    \n"; + responseStream << "

    Copyright © Gradido 2020

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "

    Login Server in Entwicklung

    \n"; + responseStream << "

    Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/UserUpdateGroupPage.h b/src/cpp/HTTPInterface/UserUpdateGroupPage.h new file mode 100644 index 000000000..5b1e9a7d1 --- /dev/null +++ b/src/cpp/HTTPInterface/UserUpdateGroupPage.h @@ -0,0 +1,20 @@ +#ifndef UserUpdateGroupPage_INCLUDED +#define UserUpdateGroupPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class UserUpdateGroupPage: public SessionHTTPRequestHandler +{ +public: + UserUpdateGroupPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // UserUpdateGroupPage_INCLUDED diff --git a/src/cpp/ImportantTests.cpp b/src/cpp/ImportantTests.cpp index d321bab5f..33c7d0f26 100644 --- a/src/cpp/ImportantTests.cpp +++ b/src/cpp/ImportantTests.cpp @@ -2,7 +2,7 @@ #include #include "ServerConfig.h" -#include "Crypto/KeyPair.h" +//#include "Crypto/KeyPair.h" #include "Crypto/KeyPairEd25519.h" #include "lib/DataTypeConverter.h" @@ -38,27 +38,36 @@ namespace ImportantTests { // test old key pair implementation - KeyPair keys; + //KeyPair keys; bool errorsOccured = false; - std::string filtered_1_de = KeyPair::filterPassphrase(passphrase_1_de); - keys.generateFromPassphrase(filtered_1_de.data(), de_words); - if (keys.getPubkeyHex() != passphrase_1_pubkey_hex) { + std::string filtered_1_de = Passphrase::filter(passphrase_1_de); + KeyPairEd25519* keys = nullptr; + keys = KeyPairEd25519::create(Passphrase::create(filtered_1_de, de_words)); + std::string public_key_hex = keys->getPublicKeyHex(); + + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_1_pubkey_hex) { printf("1 de incorrect\n"); errorsOccured = true; } - keys.generateFromPassphrase(passphrase_1_en.data(), en_words); - if (keys.getPubkeyHex() != passphrase_1_pubkey_hex) { + delete keys; + keys = KeyPairEd25519::create(Passphrase::create(passphrase_1_en, en_words)); + public_key_hex = keys->getPublicKeyHex(); + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_1_pubkey_hex) { printf("1 en incorrect\n"); errorsOccured = true; } - std::string filtered_2_de = KeyPair::filterPassphrase(passphrase_2_de); - keys.generateFromPassphrase(filtered_2_de.data(), de_words); - if (keys.getPubkeyHex() != passphrase_2_pubkey_hex) { + std::string filtered_2_de = Passphrase::filter(passphrase_2_de); + delete keys; + keys = KeyPairEd25519::create(Passphrase::create(filtered_2_de, de_words)); + public_key_hex = keys->getPublicKeyHex(); + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_2_pubkey_hex) { printf("2 de incorrect\n"); errorsOccured = true; } - keys.generateFromPassphrase(passphrase_2_en.data(), en_words); - if (keys.getPubkeyHex() != passphrase_2_pubkey_hex) { + delete keys; + keys = KeyPairEd25519::create(Passphrase::create(passphrase_2_en, en_words)); + public_key_hex = keys->getPublicKeyHex(); + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_2_pubkey_hex) { printf("2 en incorrect\n"); errorsOccured = true; } diff --git a/src/cpp/JSONInterface/JsonCreateUser.cpp b/src/cpp/JSONInterface/JsonCreateUser.cpp index 63d1cf1f4..a13832853 100644 --- a/src/cpp/JSONInterface/JsonCreateUser.cpp +++ b/src/cpp/JSONInterface/JsonCreateUser.cpp @@ -12,6 +12,7 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) std::string first_name; std::string last_name; int emailType; + int group_id; auto em = EmailManager::getInstance(); // if is json object @@ -27,6 +28,7 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) paramJsonObject->get("first_name").convert(first_name); paramJsonObject->get("last_name").convert(last_name); paramJsonObject->get("emailType").convert(emailType); + paramJsonObject->get("group_id").convert(group_id); } catch (Poco::Exception& ex) { return stateError("json exception", ex.displayText()); @@ -45,7 +47,7 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) } // create user - user = controller::User::create(email, first_name, last_name); + user = controller::User::create(email, first_name, last_name, group_id); auto userModel = user->getModel(); if (!userModel->insertIntoDB(true)) { userModel->sendErrorsAsEmail(); diff --git a/src/cpp/JSONInterface/JsonTransaction.cpp b/src/cpp/JSONInterface/JsonTransaction.cpp index 777fca295..7e09dd55d 100644 --- a/src/cpp/JSONInterface/JsonTransaction.cpp +++ b/src/cpp/JSONInterface/JsonTransaction.cpp @@ -33,10 +33,6 @@ Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params) if (!paramJsonObject->isNull("balance")) { paramJsonObject->get("balance").convert(balance); if (balance) { - auto u = session->getUser(); - if (u) { - u->setBalance(balance); - } auto nu = session->getNewUser(); if (!nu.isNull()) { nu->setBalance(balance); diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index ba07a066c..95549687a 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -21,6 +21,7 @@ namespace controller { : mPassword(nullptr), mGradidoKeyPair(nullptr), mCanDecryptPrivateKey(false), mGradidoCurrentBalance(0) { mDBModel = dbModel; + } User::~User() @@ -39,9 +40,9 @@ namespace controller { return Poco::AutoPtr(user); } - Poco::AutoPtr User::create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) + Poco::AutoPtr User::create(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) { - auto db = new model::table::User(email, first_name, last_name, passwordHashed, languageKey); + auto db = new model::table::User(email, first_name, last_name, group_id, passwordHashed, languageKey); auto user = new User(db); return Poco::AutoPtr(user); } @@ -327,6 +328,41 @@ namespace controller { return -1; } + /* + USER_EMPTY, + USER_LOADED_FROM_DB, + USER_PASSWORD_INCORRECT, + USER_PASSWORD_ENCRYPTION_IN_PROCESS, + USER_EMAIL_NOT_ACTIVATED, + USER_NO_KEYS, + USER_NO_PRIVATE_KEY, + USER_NO_GROUP, + USER_KEYS_DONT_MATCH, + USER_COMPLETE, + USER_DISABLED + */ + UserState User::getUserState() + { + std::unique_lock _lock(mSharedMutex); + auto model = getModel(); + if (!model->getID() && model->getEmail() == "") { + return USER_EMPTY; + } + if (!model->hasPrivateKeyEncrypted() && !model->hasPublicKey()) { + return USER_NO_KEYS; + } + if (!model->hasPrivateKeyEncrypted()) { + return USER_NO_PRIVATE_KEY; + } + if (!model->getGroupId()) { + return USER_NO_GROUP; + } + if (!model->isEmailChecked()) { + return USER_EMAIL_NOT_ACTIVATED; + } + return USER_COMPLETE; + } + int User::checkIfVerificationEmailsShouldBeResend(const Poco::Util::Timer& timer) { diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index a400d2ff5..1b60852b5 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -9,6 +9,21 @@ #include "TableControllerBase.h" +enum UserState +{ + USER_EMPTY, + USER_LOADED_FROM_DB, + USER_PASSWORD_INCORRECT, + USER_PASSWORD_ENCRYPTION_IN_PROCESS, + USER_EMAIL_NOT_ACTIVATED, + USER_NO_KEYS, + USER_NO_PRIVATE_KEY, + USER_NO_GROUP, + USER_KEYS_DONT_MATCH, + USER_COMPLETE, + USER_DISABLED +}; + namespace controller { @@ -26,7 +41,7 @@ namespace controller { ~User(); static Poco::AutoPtr create(); - static Poco::AutoPtr create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); + static Poco::AutoPtr create(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); static std::vector search(const std::string& searchString); @@ -96,6 +111,9 @@ namespace controller { //! \return -1 = stored pubkey and private key didn't match int setNewPassword(const std::string& password); + //! \brief calculate user state + UserState getUserState(); + //! \brief return AuthenticatedEncryption Auto Pointer inline const Poco::AutoPtr getPassword() { std::shared_lock _lock(mSharedMutex); diff --git a/src/cpp/controller/UserBackup.cpp b/src/cpp/controller/UserBackup.cpp index 9a152592f..88bc3f682 100644 --- a/src/cpp/controller/UserBackup.cpp +++ b/src/cpp/controller/UserBackup.cpp @@ -48,17 +48,12 @@ namespace controller { } - Poco::SharedPtr UserBackup::getKeyPair() + Poco::SharedPtr UserBackup::getKeyPair() { if (!mKeyPair.isNull()) { return mKeyPair; } - mKeyPair = new KeyPair; - auto model = getModel(); - auto passphrase = model->getPassphrase(); - - mKeyPair->generateFromPassphrase(passphrase); - return mKeyPair; + mKeyPair = createGradidoKeyPair(); } KeyPairEd25519* UserBackup::createGradidoKeyPair() @@ -77,17 +72,17 @@ namespace controller { return ""; } auto passphrase = getModel()->getPassphrase(); - Mnemonic* wordSource = nullptr; - if (KeyPair::validatePassphrase(passphrase, &wordSource)) { - for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { - Mnemonic* m = &ServerConfig::g_Mnemonic_WordLists[i]; - if (m == wordSource) { - if (type == i) { - return passphrase; - } - else { - return KeyPair::passphraseTransform(passphrase, m, &ServerConfig::g_Mnemonic_WordLists[type]); - } + auto wordSource = Passphrase::detectMnemonic(passphrase); + for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { + Mnemonic* m = &ServerConfig::g_Mnemonic_WordLists[i]; + if (m == wordSource) { + if (type == i) { + return passphrase; + } + else { + //return KeyPair::passphraseTransform(passphrase, m, &ServerConfig::g_Mnemonic_WordLists[type]); + auto passphrase_obj = Passphrase::create(passphrase, wordSource); + return passphrase_obj->transform(&ServerConfig::g_Mnemonic_WordLists[type])->getString(); } } } diff --git a/src/cpp/controller/UserBackup.h b/src/cpp/controller/UserBackup.h index a21d1c3ab..f1ab2f95a 100644 --- a/src/cpp/controller/UserBackup.h +++ b/src/cpp/controller/UserBackup.h @@ -2,7 +2,6 @@ #define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE #include "../model/table/UserBackup.h" -#include "../Crypto/KeyPair.h" #include "../Crypto/KeyPairEd25519.h" #include "Poco/SharedPtr.h" @@ -26,7 +25,7 @@ namespace controller { //! depracted //! \return create keyPair from passphrase if not exist, else return existing pointer - Poco::SharedPtr getKeyPair(); + Poco::SharedPtr getKeyPair(); //! \return newly created key pair from passphrase or nullptr if not possible, caller becomes owner of pointer KeyPairEd25519* createGradidoKeyPair(); @@ -38,7 +37,7 @@ namespace controller { protected: UserBackup(model::table::UserBackup* dbModel); - Poco::SharedPtr mKeyPair; + Poco::SharedPtr mKeyPair; }; } diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 2e24e8610..ae3138233 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -34,59 +34,12 @@ using namespace Poco::Data::Keywords; -int WriteEmailVerification::run() -{ - auto em = ErrorManager::getInstance(); - - mEmailVerificationCode->getModel()->setUserId(mUser->getDBId()); - auto emailVerificationModel = mEmailVerificationCode->getModel(); - emailVerificationModel->setUserId(mUser->getDBId()); - if (!emailVerificationModel->insertIntoDB(true) || emailVerificationModel->errorCount() > 0) { - emailVerificationModel->sendErrorsAsEmail(); - return -1; - } - - return 0; -} - -// --------------------------------------------------------------------------------------------------------------- - -int WritePassphraseIntoDB::run() -{ - Profiler timeUsed; - - // TODO: encrypt passphrase, need server admin crypto box pubkey - //int crypto_box_seal(unsigned char *c, const unsigned char *m, - //unsigned long long mlen, const unsigned char *pk); - size_t mlen = mPassphrase.size(); - size_t crypto_size = crypto_box_SEALBYTES + mlen; - - auto em = ErrorManager::getInstance(); - - auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement insert(dbSession); - insert << "INSERT INTO user_backups (user_id, passphrase) VALUES(?,?)", - use(mUserId), use(mPassphrase); - try { - if (insert.execute() != 1) { - em->addError(new ParamError("WritePassphraseIntoDB::run", "inserting passphrase for user failed", std::to_string(mUserId))); - em->sendErrorsAsEmail(); - } - } - catch (Poco::Exception& ex) { - em->addError(new ParamError("WritePassphraseIntoDB::run", "insert passphrase mysql error", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - - //printf("[WritePassphraseIntoDB] timeUsed: %s\n", timeUsed.string().data()); - return 0; -} // -------------------------------------------------------------------------------------------------------------- Session::Session(int handle) - : mHandleId(handle), mSessionUser(nullptr), mState(SESSION_STATE_EMPTY), mActive(false) + : mHandleId(handle), mState(SESSION_STATE_EMPTY), mActive(false) { } @@ -109,7 +62,6 @@ void Session::reset() //printf("[Session::reset]\n"); lock("Session::reset"); std::unique_lock _lock(mSharedMutex); - mSessionUser.assign(nullptr); mNewUser.assign(nullptr); mEmailVerificationCodeObject.assign(nullptr); @@ -147,7 +99,7 @@ Poco::AutoPtr Session::getEmailVerificationCo return ret; } -bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email) +bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email, int group_id) { Profiler usedTime; @@ -177,7 +129,7 @@ bool Session::adminCreateUser(const std::string& first_name, const std::string& return false; } - auto newUser = controller::User::create(email, first_name, last_name); + auto newUser = controller::User::create(email, first_name, last_name, group_id); updateTimeout(); @@ -201,128 +153,9 @@ bool Session::adminCreateUser(const std::string& first_name, const std::string& return true; } -// -bool Session::createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) -{ - Profiler usedTime; - auto sm = SessionManager::getInstance(); - if (!sm->isValid(first_name, VALIDATE_NAME)) { - addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(last_name, VALIDATE_NAME)) { - addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(email, VALIDATE_EMAIL)) { - addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); - return false; - } - if (!sm->checkPwdValidation(password, this)) { - return false; - } - /*if (passphrase.size() > 0 && !sm->isValid(passphrase, VALIDATE_PASSPHRASE)) { - addError(new Error("Merkspruch", "Der Merkspruch ist nicht gültig, er besteht aus 24 Wörtern, mit Komma getrennt.")); - return false; - } - if (passphrase.size() == 0) { - //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - } - else { - //mPassphrase = passphrase; - }*/ - // check if user with that email already exist - auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement select(dbConnection); - select << "SELECT email from users where email = ?;", useRef(email); - try { - if (select.execute() > 0) { - addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits einen Account")), false); - return false; - } - } - catch (Poco::Exception& exc) { - printf("mysql exception: %s\n", exc.displayText().data()); - } - - mSessionUser = new User(email.data(), first_name.data(), last_name.data()); - mNewUser = controller::User::create(email, first_name, last_name); - updateTimeout(); - - // Prepare E-Mail - //UniLib::controller::TaskPtr prepareEmail(new PrepareEmailTask(ServerConfig::g_CPUScheduler)); - //prepareEmail->scheduleTask(prepareEmail); - - // create user crypto key - UniLib::controller::TaskPtr cryptoKeyTask(new UserCreateCryptoKey(mSessionUser, mNewUser, password, ServerConfig::g_CryptoCPUScheduler)); - cryptoKeyTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_CRYPTO_KEY_GENERATED, this)); - cryptoKeyTask->scheduleTask(cryptoKeyTask); - - // depends on crypto key, write user record into db - UniLib::controller::TaskPtr writeUserIntoDB(new UserWriteIntoDB(mSessionUser, ServerConfig::g_CPUScheduler, 1)); - writeUserIntoDB->setParentTaskPtrInArray(cryptoKeyTask, 0); - writeUserIntoDB->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_USER_WRITTEN, this)); - writeUserIntoDB->scheduleTask(writeUserIntoDB); - - std::unique_lock _lock(mSharedMutex); - mEmailVerificationCodeObject = controller::EmailVerificationCode::create(model::table::EMAIL_OPT_IN_REGISTER); - UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, mEmailVerificationCodeObject, ServerConfig::g_CPUScheduler, 1)); - - writeEmailVerification->setParentTaskPtrInArray(writeUserIntoDB, 0); - writeEmailVerification->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, this)); - writeEmailVerification->scheduleTask(writeEmailVerification); - - - /*printf("LastName: %s\n", last_name.data()); - for (int i = 0; i < last_name.size(); i++) { - char c = last_name.data()[i]; - //printf("%d ", c); - } - //printf("\n\n"); - */ - - // depends on writeUser because need user_id, write email verification into db - /*auto message = new Poco::Net::MailMessage; - Poco::Net::MediaType mt("text", "plain"); - mt.setParameter("charset", "utf-8"); - message->setContentType(mt); - - message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, email)); - message->setSubject(gettext("Gradido: E-Mail Verification")); - std::stringstream ss; - ss << "Hallo " << first_name << " " << last_name << "," << std::endl << std::endl; - ss << "Du oder jemand anderes hat sich soeben mit dieser E-Mail Adresse bei Gradido registriert. " << std::endl; - ss << "Wenn du es warst, klicke bitte auf den Link: " << ServerConfig::g_serverPath << "/checkEmail/" << mEmailVerificationCode << std::endl; - //ss << "oder kopiere den Code: " << mEmailVerificationCode << " selbst dort hinein." << std::endl; - ss << "oder kopiere den obigen Link in Dein Browserfenster." << std::endl; - ss << std::endl; - ss << "Mit freundlichen " << u8"Grüßen" << std::endl; - ss << "Dario, Gradido Server Admin" << std::endl; - - - message->addContent(new Poco::Net::StringPartSource(ss.str())); - */ - //UniLib::controller::TaskPtr sendEmail(new SendEmailTask(message, ServerConfig::g_CPUScheduler, 1)); - //Email(AutoPtr emailVerification, AutoPtr user, EmailType type); - UniLib::controller::TaskPtr sendEmail(new SendEmailTask(new model::Email(mEmailVerificationCodeObject, mNewUser, model::EMAIL_USER_VERIFICATION_CODE), ServerConfig::g_CPUScheduler, 1)); - //sendEmail->setParentTaskPtrInArray(prepareEmail, 0); - sendEmail->setParentTaskPtrInArray(writeEmailVerification, 0); - sendEmail->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_SEND, this)); - sendEmail->scheduleTask(sendEmail); - - // write user into db - // generate and write email verification into db - // send email - - //printf("[Session::createUser] time: %s\n", usedTime.string().data()); - - return true; -} - -bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) +bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password, int groupId) { std::unique_lock _lock(mSharedMutex); static const char* function_name = "Session::createUserDirect"; @@ -354,7 +187,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string& } // user - mNewUser = controller::User::create(email, first_name, last_name); + mNewUser = controller::User::create(email, first_name, last_name, groupId); auto user_model = mNewUser->getModel(); user_model->insertIntoDB(true); auto user_id = user_model->getID(); @@ -429,16 +262,8 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) } auto email_verification_code_model = mEmailVerificationCodeObject->getModel(); assert(email_verification_code_model); - if(email_verification_code_model->getCode() == emailVerificationCode) { - if (mSessionUser && mSessionUser->getDBId() == 0) { - //addError(new Error("E-Mail Verification", "Benutzer wurde nicht richtig gespeichert, bitte wende dich an den Server-Admin")); - em->addError(new Error(funcName, "user exist with 0 as id")); - em->sendErrorsAsEmail(); - - //return false; - return -2; - } - + if(email_verification_code_model->getCode() == emailVerificationCode) + { // load correct user from db if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getModel()->getID() != email_verification_code_model->getUserId()) { mNewUser = controller::User::create(); @@ -460,7 +285,6 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) first_email_activation = true; } if (first_email_activation && user_model->isEmailChecked()) { - mSessionUser = new User(mNewUser); addError(new Error(gettext("E-Mail Verification"), gettext("Du hast dein Konto bereits aktiviert!")), false); return 1; @@ -499,28 +323,6 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) return -2; - /*if (updated_rows == 1) { - Poco::Data::Statement delete_row(dbConnection); - delete_row << "DELETE FROM email_opt_in where verification_code = ?", use(emailVerificationCode); - if (delete_row.execute() != 1) { - em->addError(new Error(funcName, "delete from email_opt_in entry didn't work as expected, please check db")); - em->sendErrorsAsEmail(); - } - if (mSessionUser) { - mSessionUser->setEmailChecked(); - mSessionUser->setLanguage(getLanguage()); - } - updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); - //printf("[%s] time: %s\n", funcName, usedTime.string().data()); - unlock(); - return true; - } - else { - em->addError(new ParamError(funcName, "update user work not like expected, updated row count", updated_rows)); - em->sendErrorsAsEmail(); - }*/ - - } else { addError(new Error(gettext("E-Mail Verification"), gettext("Falscher Code für aktiven Login"))); @@ -537,7 +339,6 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) int Session::sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized) { mNewUser = user; - mSessionUser = new User(user); auto em = EmailManager::getInstance(); std::unique_lock _lock(mSharedMutex); @@ -579,16 +380,17 @@ int Session::sendResetPasswordEmail(Poco::AutoPtr user, bool p return 0; } -int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource) +int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, const Mnemonic* wordSource) { - KeyPair keys; + static const char* functionName = "Session::comparePassphraseWithSavedKeys"; if (!wordSource) { addError(new Error(functionName, "wordSource is empty")); sendErrorsAsEmail(); return -2; } - if (!keys.generateFromPassphrase(inputPassphrase.data(), wordSource)) { + auto passphrase = Passphrase::create(inputPassphrase, wordSource); + if (passphrase.isNull() || !passphrase->checkIfValid()) { addError(new ParamError(functionName, "invalid passphrase", inputPassphrase)); if (!mNewUser.isNull() && mNewUser->getModel()) { addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); @@ -610,9 +412,15 @@ int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, return -1; } } - if (0 == memcmp(userModel->getPublicKey(), keys.getPublicKey(), crypto_sign_PUBLICKEYBYTES)) { - mPassphrase = inputPassphrase; - return 1; + auto keys = KeyPairEd25519::create(passphrase); + if (keys) { + auto cmp_result = memcmp(userModel->getPublicKey(), keys->getPublicKey(), crypto_sign_PUBLICKEYBYTES); + delete keys; + keys = nullptr; + if (0 == cmp_result) { + mPassphrase = inputPassphrase; + return 1; + } } addError(new Error(gettext("Passphrase"), gettext("Das ist nicht die richtige Passphrase.")), false); return 0; @@ -634,13 +442,8 @@ bool Session::startProcessingTransaction(const std::string& proto_message_base64 return false; } } - if (mSessionUser.isNull() || !mSessionUser->getEmail()) { - addError(new Error(funcName, "user is zero")); - unlock(); - return false; - } - Poco::AutoPtr processorTask(new ProcessingTransaction(proto_message_base64, DRMakeStringHash(mSessionUser->getEmail()))); + Poco::AutoPtr processorTask(new ProcessingTransaction(proto_message_base64, DRMakeStringHash(mNewUser->getModel()->getEmail().data()))); processorTask->scheduleTask(processorTask); mProcessingTransactions.push_back(processorTask); unlock(); @@ -723,15 +526,7 @@ size_t Session::getProcessingTransactionCount() return count; } -bool Session::isPwdValid(const std::string& pwd) -{ - if (mSessionUser) { - return mSessionUser->validatePwd(pwd, this); - } - return false; -} - -UserStates Session::loadUser(const std::string& email, const std::string& password) +UserState Session::loadUser(const std::string& email, const std::string& password) { static const char* functionName = "Session::loadUser"; auto observer = SingletonTaskObserver::getInstance(); @@ -742,24 +537,20 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo } //Profiler usedTime; lock(functionName); - if (mSessionUser && mSessionUser->getEmail() != email) { - mSessionUser.assign(nullptr); - mNewUser.assign(nullptr); - } + //if (!mSessionUser) { if (mNewUser.isNull()) { mNewUser = controller::User::create(); // load user for email only once from db mNewUser->load(email); - mSessionUser = new User(mNewUser); - //mSessionUser = new User(email.data()); + } auto user_model = mNewUser->getModel(); if (user_model && user_model->isDisabled()) { return USER_DISABLED; } - if (mSessionUser->getUserState() >= USER_LOADED_FROM_DB) { + if (mNewUser->getUserState() >= USER_LOADED_FROM_DB) { int loginResult = mNewUser->login(password); if (-1 == loginResult) { @@ -798,42 +589,30 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo } } } - // can be removed if session user isn't used any more - // don't calculate password two times anymore - mSessionUser->login(mNewUser); - /*if (mNewUser->getModel()->getPasswordHashed() && !mSessionUser->validatePwd(password, this)) { - unlock(); - return USER_PASSWORD_INCORRECT; - }*/ + } else { - User::fakeCreateCryptoKey(); + Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime); } - /*if (!mSessionUser->validatePwd(password, this)) { - addError(new Error("Login", "E-Mail oder Passwort nicht korrekt, bitte versuche es erneut!")); - unlock(); - return false; - } - if (!mSessionUser->isEmailChecked()) { - addError(new Error("Account", "E-Mail Adresse wurde noch nicht bestätigt, hast du schon eine E-Mail erhalten?")); - unlock(); - return false; - }*/ detectSessionState(); unlock(); + if (0 == mNewUser->getModel()->getGroupId()) { + return USER_NO_GROUP; + } - return mSessionUser->getUserState(); + return mNewUser->getUserState(); } bool Session::deleteUser() { lock("Session::deleteUser"); bool bResult = false; - if(mSessionUser) { + if(!mNewUser.isNull()) { JsonRequest phpServerRequest(ServerConfig::g_php_serverHost, 443); Poco::Net::NameValueCollection payload; - payload.add("user", std::string(mSessionUser->getPublicKeyHex())); + auto user_model = mNewUser->getModel(); + payload.add("user", user_model->getPublicKeyHex()); //auto ret = phpServerRequest.request("userDelete", payload); JsonRequestReturn ret = JSON_REQUEST_RETURN_OK; if (ret == JSON_REQUEST_RETURN_ERROR) { @@ -842,7 +621,7 @@ bool Session::deleteUser() sendErrorsAsEmail(); } else if (ret == JSON_REQUEST_RETURN_OK) { - bResult = mSessionUser->deleteFromDB(); + bResult = user_model->deleteFromDB(); } else { addError(new Error(gettext("Benutzer"), gettext("Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."))); @@ -895,14 +674,14 @@ SESSION_STATE_COUNT */ void Session::detectSessionState() { - if (!mSessionUser || !mSessionUser->hasCryptoKey()) { + if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getPassword().isNull()) { return; } - UserStates userState = mSessionUser->getUserState(); + UserState userState = mNewUser->getUserState(); int checkEmail = -1, resetPasswd = -1; try { - auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mSessionUser->getDBId()); + auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mNewUser->getModel()->getID()); for (int i = 0; i < emailVerificationCodeObjects.size(); i++) { auto type = emailVerificationCodeObjects[i]->getModel()->getType(); @@ -940,7 +719,7 @@ void Session::detectSessionState() if (USER_NO_KEYS == userState) { - auto user_id = mSessionUser->getDBId(); + auto user_id = mNewUser->getModel()->getID(); auto userBackups = controller::UserBackup::load(user_id); // check passphrase, only possible while passphrase isn't crypted in db @@ -948,15 +727,20 @@ void Session::detectSessionState() // always trigger SESSION_STATE_PASSPHRASE_WRITTEN, else lost of data possible bool cryptedPassphrase = userBackups.size() > 0; for (auto it = userBackups.begin(); it != userBackups.end(); it++) { - KeyPair keys; auto passphrase = (*it)->getModel()->getPassphrase(); Mnemonic* wordSource = nullptr; - if (User::validatePassphrase(passphrase, &wordSource)) { - if (keys.generateFromPassphrase((*it)->getModel()->getPassphrase().data(), wordSource)) { - if (sodium_memcmp(mSessionUser->getPublicKey(), keys.getPublicKey(), ed25519_pubkey_SIZE) == 0) { - correctPassphraseFound = true; - break; - } + auto passphrase_obj = Passphrase::create(passphrase, wordSource); + if (!passphrase_obj.isNull() && passphrase_obj->checkIfValid()) { + auto key_pair = KeyPairEd25519::create(passphrase_obj); + if (key_pair && key_pair->isTheSame(mNewUser->getModel()->getPublicKey())) { + correctPassphraseFound = true; + //break; + } + if (key_pair) { + delete key_pair; + } + if (correctPassphraseFound) { + break; } } else { @@ -1038,8 +822,7 @@ bool Session::loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode) addError(new Error(gettext("E-Mail Verification"), gettext("Fehler beim laden des Benutzers."))); return false; } - mSessionUser = new User(mNewUser); - mSessionUser->setLanguage(getLanguage()); + // TODO: Maybe update language key by user, is session has another, or update only with options-menu auto verificationType = mEmailVerificationCodeObject->getModel()->getType(); if (verificationType == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { @@ -1117,21 +900,7 @@ bool Session::useOrGeneratePassphrase(const std::string& passphase) } } */ -bool Session::generatePassphrase() -{ - if (mNewUser.isNull()) return false; - - auto lang = getLanguage(); - if (lang == LANG_EN) { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); - } - else { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - } - //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - updateState(SESSION_STATE_PASSPHRASE_GENERATED); - return true; -} + bool Session::generateKeys(bool savePrivkey, bool savePassphrase) { diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index 6557ef30e..8834b63fd 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -11,7 +11,6 @@ #define DR_LUA_WEB_MODULE_SESSION_SESSION_H #include "../lib/NotificationList.h" -#include "User.h" #include "../controller/User.h" #include "../lib/MultithreadContainer.h" @@ -73,29 +72,20 @@ public: inline Poco::AutoPtr getNewUser() { return mNewUser; } // ---------------- User functions ---------------------------- - // TODO: register state: written into db, mails sended, update state only if new state is higher as old state - // create User send e-mail activation link - bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); //! \brief new register function, without showing user pubkeys, using controller/user - bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password, int groupId); // adminRegister without passwort - bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); + bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email, int group_id); // TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing - UserStates loadUser(const std::string& email, const std::string& password); + UserState loadUser(const std::string& email, const std::string& password); bool ifUserExist(const std::string& email); - - inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } - bool deleteUser(); - Poco::AutoPtr getUser() { - return mSessionUser; - } // ------------------------- Email Verification Code functions ------------------------------- @@ -117,7 +107,7 @@ public: //! \return 1 = same //! \return -1 = error //! \return -2 = critical error - int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource); + int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, const Mnemonic* wordSource); Poco::Net::HTTPCookie getLoginCookie(); @@ -132,14 +122,13 @@ public: inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; } inline const std::string& getOldPassphrase() { return mPassphrase; } - bool generatePassphrase(); + bool generateKeys(bool savePrivkey, bool savePassphrase); inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; } inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; } inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; } - bool isPwdValid(const std::string& pwd); void reset(); void updateState(SessionStates newState); @@ -198,7 +187,6 @@ protected: private: int mHandleId; - Poco::AutoPtr mSessionUser; Poco::AutoPtr mNewUser; std::string mPassphrase; Poco::AutoPtr mNewPassphrase; @@ -219,44 +207,6 @@ private: }; -class WriteEmailVerification : public UniLib::controller::CPUTask -{ -public: - WriteEmailVerification(Poco::AutoPtr user, Poco::AutoPtr emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) - : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - virtual const char* getResourceType() const { return "WriteEmailVerification"; }; - virtual int run(); - -private: - Poco::AutoPtr mUser; - Poco::AutoPtr mEmailVerificationCode; - -}; - -class WritePassphraseIntoDB : public UniLib::controller::CPUTask -{ -public: - WritePassphraseIntoDB(int userId, const std::string& passphrase) - : mUserId(userId), mPassphrase(passphrase) { -#ifdef _UNI_LIB_DEBUG - setName(std::to_string(userId).data()); -#endif - } - - - virtual int run(); - virtual const char* getResourceType() const { return "WritePassphraseIntoDB"; }; - -protected: - int mUserId; - std::string mPassphrase; -}; - class SessionStateUpdateCommand : public UniLib::controller::Command { public: diff --git a/src/cpp/model/TransactionCreation.cpp b/src/cpp/model/TransactionCreation.cpp index 499aef61d..fd80660d8 100644 --- a/src/cpp/model/TransactionCreation.cpp +++ b/src/cpp/model/TransactionCreation.cpp @@ -3,17 +3,14 @@ #include TransactionCreation::TransactionCreation(const std::string& memo, const proto::gradido::GradidoCreation& protoCreation) - : TransactionBase(memo), mProtoCreation(protoCreation), mReceiverUser(nullptr) + : TransactionBase(memo), mProtoCreation(protoCreation) { memset(mReceiverPublicHex, 0, 65); } TransactionCreation::~TransactionCreation() { - if (mReceiverUser) { - delete mReceiverUser; - mReceiverUser = nullptr; - } + } int TransactionCreation::prepare() @@ -30,15 +27,17 @@ int TransactionCreation::prepare() addError(new Error(functionName, "receiver public invalid (size not 32)")); return -2; } - mReceiverUser = new User((const unsigned char*)receiverPublic.data()); - getErrors(mReceiverUser); + mReceiverUser = controller::User::create(); + //mReceiverUser = new User((const unsigned char*)receiverPublic.data()); + mReceiverUser->load((const unsigned char*)receiverPublic.data()); + getErrors(mReceiverUser->getModel()); if (mReceiverUser->getUserState() == USER_EMPTY) { sodium_bin2hex(mReceiverPublicHex, 65, (const unsigned char*)receiverPublic.data(), receiverPublic.size()); delete mReceiverUser; mReceiverUser = nullptr; } else { - memcpy(mReceiverPublicHex, mReceiverUser->getPublicKeyHex().data(), 64); + memcpy(mReceiverPublicHex, mReceiverUser->getModel()->getPublicKeyHex().data(), 64); // uncomment because not correctly working /*if (!mReceiverUser->validateIdentHash(mProtoCreation.ident_hash())) { addError(new Error(functionName, "ident hash isn't the same")); diff --git a/src/cpp/model/TransactionCreation.h b/src/cpp/model/TransactionCreation.h index ff1fd62a8..fe695b89b 100644 --- a/src/cpp/model/TransactionCreation.h +++ b/src/cpp/model/TransactionCreation.h @@ -13,7 +13,7 @@ #include "TransactionBase.h" #include "../proto/gradido/GradidoCreation.pb.h" -#include "User.h" +#include "../controller/User.h" class TransactionCreation : public TransactionBase { @@ -23,7 +23,7 @@ public: int prepare(); - inline User* getUser() { return mReceiverUser; } + inline Poco::AutoPtr getUser() { return mReceiverUser; } inline google::protobuf::int64 getAmount() { return mProtoCreation.receiver().amount(); } inline char* getPublicHex() { return mReceiverPublicHex; } @@ -33,7 +33,7 @@ public: protected: const proto::gradido::GradidoCreation& mProtoCreation; char mReceiverPublicHex[65]; - User* mReceiverUser; + Poco::AutoPtr mReceiverUser; }; #endif //GRADIDO_LOGIN_SERVER_MODEL_TRANSACTION_CREATION_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp deleted file mode 100644 index a57324cf8..000000000 --- a/src/cpp/model/User.cpp +++ /dev/null @@ -1,1323 +0,0 @@ -#include "User.h" -#include "Session.h" -#include -#include "ed25519/ed25519.h" -#include "Poco/Util/Application.h" -#include "Poco/RegularExpression.h" -#include "../ServerConfig.h" - -#include "../SingletonManager/ConnectionManager.h" -#include "../SingletonManager/ErrorManager.h" -#include "../SingletonManager/SessionManager.h" -#include "../SingletonManager/LanguageManager.h" -#include "../SingletonManager/SingletonTaskObserver.h" - -#include "../controller/UserBackup.h" - - -#include "Poco/Data/Binding.h" - -using namespace Poco::Data::Keywords; - -//#define DEBUG_USER_DELETE_ENV - - -// ------------------------------------------------------------------------------------------------- - -UserCreateCryptoKey::UserCreateCryptoKey(Poco::AutoPtr user, Poco::AutoPtr newUser, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler) - : UniLib::controller::CPUTask(cpuScheduler), mUser(user), mNewUser(newUser), mPassword(password) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - -} - -int UserCreateCryptoKey::run() -{ - auto cryptoKey = mUser->createCryptoKey(mPassword); - mUser->setCryptoKey(cryptoKey); - - if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { - printf("[UserCreateCryptoKey] crypto_shorthash_BYTES != sizeof(mPasswordHashed)\n"); - throw Poco::Exception("crypto_shorthash_BYTES != sizeof(mPasswordHashed)"); - } - - auto pwdHashed = mUser->createPasswordHashed(cryptoKey); - mUser->setPwdHashed(pwdHashed); - mNewUser->getModel()->setPasswordHashed(pwdHashed); - - //printf("crypto key created\n"); - setTaskFinished(); - // must poke cpu scheduler manually because another task is waiting for this task, but in the other scheduler - ServerConfig::g_CPUScheduler->checkPendingTasks(); - return 0; -} - -// ------------------------------------------------------------------------------------------------------------- - -int UserGenerateKeys::run() -{ - - Mnemonic* wordList = nullptr; - if (!User::validatePassphrase(mPassphrase, &wordList)) { - mUser->addError(new Error(mUser->gettext("User generate Keys"), mUser->gettext("invalid passphrase, please notice the server admin coin@gradido.net"))); - return -2; - } - - // always return true, cannot fail (only if low on memory) - // !!! update: now can fail, if passphrase is invalid, for example if memory is corrupted - if (!mKeys.generateFromPassphrase(mPassphrase.data(), wordList)) { - mUser->addError(new Error(mUser->gettext("User generate Keys"), mUser->gettext("invalid passphrase2, please notice the server admin coin@gradido.net"))); - return -1; - } - - mUser->setPublicKeyHex(mKeys.getPubkeyHex()); - mUser->setPublicKey(mKeys.getPublicKey()); - - auto newUserModel = mNewUser->getModel(); - - newUserModel->setPublicKey(mKeys.getPublicKey()); - if (mUser->hasCryptoKey()) { - mUser->setPrivKey(mKeys.getPrivateKey()); - newUserModel->setPrivateKey(mUser->getPrivKey()); - } - - //printf("[UserGenerateKeys::run] controller::User: %d\n", (int)mNewUser.get()); - - return 0; -} - -// ----------------------------------------------------------------------------------------------------- - -int UserWriteIntoDB::run() -{ - auto cm = ConnectionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement insert = mUser->insertIntoDB(session); - try { - if (1 != insert.execute()) { - mUser->addError(new Error("User::insertIntoDB", "error by inserting data tuple to db")); - return -1; - } - } catch (Poco::Exception& ex) { - em->addError(new ParamError("[UserWriteIntoDB]", "error writing into db", ex.displayText().data())); - em->sendErrorsAsEmail(); - return -3; - } - if (!mUser->loadEntryDBId(session)) { - return -2; - } - return 0; -} - -// -------------------------------------------------------------------------------------------------------- - -UserWriteKeysIntoDB::UserWriteKeysIntoDB(std::vector parents, Poco::AutoPtr user, bool savePrivKey) - : UniLib::controller::CPUTask(parents.size()), mUser(user), mSavePrivKey(savePrivKey) -{ -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - if (parents.size() < 1 || strcmp(parents[0]->getResourceType(), "UserGenerateKeys") != 0) { - throw Poco::Exception("given TaskPtr isn't UserGenerateKeys"); - } - for (int i = 0; i < parents.size(); i++) { - setParentTaskPtrInArray(parents[i], i); - } - //setParentTaskPtrInArray(parents[0], 0); - -} - -int UserWriteKeysIntoDB::run() -{ - auto cm = ConnectionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - auto keyPairs = getParent(0).cast()->getKeyPairs(); - auto pubKey = keyPairs->getPublicKey(); - static const char* functionName = "UserWritePrivKeyIntoDB::run"; - - //printf("[UserWriteKeysIntoDB] after init\n"); - - Poco::Data::BLOB pubkey_blob(pubKey, crypto_sign_PUBLICKEYBYTES); - Poco::Data::Statement update(session); - Poco::Data::BLOB* pprivkey_blob = nullptr; - if (mSavePrivKey) { - //printf("[UserWriteKeysIntoDB] save privkey\n"); - // TODO: encrypt privkey - auto privKey = keyPairs->getPrivateKey(); - //printf("[UserWriteKeysIntoDB] privKey hex: %s\n", KeyPair::getHex(*privKey, privKey->size()).data()); - auto encryptedPrivKey = mUser->encrypt(privKey); - //pprivkey_blob = mUser->encrypt(privKey); - if (!encryptedPrivKey) { - em->addError(new Error(functionName, "no privkey found")); - em->sendErrorsAsEmail(); - return -1; - } - pprivkey_blob = new Poco::Data::BLOB(*encryptedPrivKey, encryptedPrivKey->size()); - //printf("[UserWriteKeysIntoDB] privkey encrypted\n"); - //Poco::Data::BLOB privkey_blob(*privKey, privKey->size()); - - update << "UPDATE users SET pubkey=?, privkey=? where id=?", - use(pubkey_blob), use(*pprivkey_blob), bind(mUser->getDBId()); - } - else { - update << "UPDATE users SET pubkey=? where id=?", - use(pubkey_blob), bind(mUser->getDBId()); - } - - try { - if (update.execute() != 1) { - em->addError(new ParamError(functionName, "error writing keys into db for user", std::to_string(mUser->getDBId()))); - em->sendErrorsAsEmail(); - if (pprivkey_blob) { - delete pprivkey_blob; - } - return -1; - } - } - catch (Poco::Exception& ex) { - em->addError(new ParamError(functionName, "mysql error updating", ex.displayText().data())); - em->sendErrorsAsEmail(); - if (pprivkey_blob) { - delete pprivkey_blob; - } - return -1; - } - - //printf("[UserWriteKeysIntoDB] after saving into db\n"); - if (pprivkey_blob) { - delete pprivkey_blob; - } - - return 0; -} - -// -------------------------------------------------------------------------------------------------------- - -UserWriteCryptoKeyHashIntoDB::UserWriteCryptoKeyHashIntoDB(Poco::AutoPtr user, int dependencieCount/* = 0*/) - : UniLib::controller::CPUTask(ServerConfig::g_CPUScheduler, dependencieCount), mUser(user) -{ -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif -} - -int UserWriteCryptoKeyHashIntoDB::run() -{ - mUser->updateIntoDB(USER_FIELDS_PASSWORD); - return 0; -} - -// ******************************************************************************* -// new user -User::User(const char* email, const char* first_name, const char* last_name) - : mState(USER_EMPTY), mDBId(0), mEmail(email), mFirstName(first_name), mLastName(last_name), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); -} -// load from db -User::User(const char* email) - : mState(USER_EMPTY), mDBId(0), mEmail(email), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - //crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); - //memset(mPasswordHashed, 0, crypto_shorthash_BYTES); - auto cm = ConnectionManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES); - - Poco::Nullable pubkey; - Poco::Nullable privkey; - - Poco::Data::Statement select(session); - int email_checked = 0; - std::string language_key; - select << "SELECT id, first_name, last_name, password, pubkey, privkey, email_checked, language from users where email = ?", - into(mDBId), into(mFirstName), into(mLastName), into(mPasswordHashed), into(pubkey), into(privkey), into(email_checked), into(language_key), - use(mEmail); - try { - auto result = select.execute(); - if (result == 1) { - mState = USER_LOADED_FROM_DB; - mLanguage = LanguageManager::languageFromString(language_key); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - if (email_checked == 0) { mState = USER_EMAIL_NOT_ACTIVATED;} - else if (pubkey.isNull()) { mState = USER_NO_KEYS;} - else if (privkey.isNull()) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE;} - - mEmailChecked = email_checked == 1; - - if (!pubkey.isNull()) { - auto pubkey_value = pubkey.value(); - if (pubkey_value.size() == crypto_sign_PUBLICKEYBYTES) { - memcpy(mPublicKey, pubkey_value.content().data(), crypto_sign_PUBLICKEYBYTES); - } - else { - addError(new Error("User", "pubkey from db has other size as expected")); - } - size_t hexSize = pubkey_value.size() * 2 + 1; - char* hexString = (char*)malloc(hexSize); - memset(hexString, 0, hexSize); - sodium_bin2hex(hexString, hexSize, pubkey_value.content().data(), pubkey_value.size()); - mPublicHex = hexString; - free(hexString); - } - if (!privkey.isNull()) { - auto privkey_value = privkey.value(); - auto privkey_size = privkey_value.size(); - //mPrivateKey = new ObfusArray(privkey_value.size(), privkey_value.content().data()); - mPrivateKey = MemoryManager::getInstance()->getFreeMemory(privkey_size); - memcpy(*mPrivateKey, privkey_value.content().data(), privkey_size); - } - - } - } catch(Poco::Exception& ex) { - addError(new ParamError("User::User", "mysql error", ex.displayText().data())); - } -} - -User::User(int user_id) - : mState(USER_EMPTY), mDBId(user_id), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - auto cm = ConnectionManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES); - - Poco::Nullable pubkey; - Poco::Nullable privkey; - - Poco::Data::Statement select(session); - int email_checked = 0; - std::string language_key; - select << "SELECT email, first_name, last_name, password, pubkey, privkey, email_checked, language from users where id = ?", - into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(pubkey), into(privkey), into(email_checked), into(language_key), - use(user_id); - try { - auto result = select.execute(); - if (result == 1) { - mState = USER_LOADED_FROM_DB; - mLanguage = LanguageManager::languageFromString(language_key); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - if (email_checked == 0) { mState = USER_EMAIL_NOT_ACTIVATED; } - else if (pubkey.isNull()) { mState = USER_NO_KEYS; } - else if (privkey.isNull()) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE; } - - mEmailChecked = email_checked == 1; - - if (!pubkey.isNull()) { - auto pubkey_value = pubkey.value(); - if (pubkey_value.size() == crypto_sign_PUBLICKEYBYTES) { - memcpy(mPublicKey, pubkey_value.content().data(), crypto_sign_PUBLICKEYBYTES); - } - else { - addError(new Error("User", "pubkey from db has other size as expected")); - } - size_t hexSize = pubkey_value.size() * 2 + 1; - char* hexString = (char*)malloc(hexSize); - memset(hexString, 0, hexSize); - sodium_bin2hex(hexString, hexSize, pubkey_value.content().data(), pubkey_value.size()); - mPublicHex = hexString; - free(hexString); - } - if (!privkey.isNull()) { - auto privkey_value = privkey.value(); - auto privkey_size = privkey_value.size(); - //mPrivateKey = new ObfusArray(privkey_value.size(), privkey_value.content().data()); - mPrivateKey = MemoryManager::getInstance()->getFreeMemory(privkey_size); - memcpy(*mPrivateKey, privkey_value.content().data(), privkey_size); - } - } - } - catch (Poco::Exception& ex) { - addError(new ParamError("User::User", "mysql error", ex.displayText().data())); - } -} - -User::User(const unsigned char* pubkey_array) - : mState(USER_EMPTY), mDBId(0), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - //crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); - //memset(mPasswordHashed, 0, crypto_shorthash_BYTES); - auto cm = ConnectionManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - memcpy(mPublicKey, pubkey_array, crypto_sign_PUBLICKEYBYTES); - - Poco::Data::BLOB pubkey(pubkey_array, 32); - Poco::Nullable privkey; - - Poco::Data::Statement select(session); - int email_checked = 0; - std::string language_key; - select << "SELECT id, email, first_name, last_name, password, privkey, email_checked, language from users where pubkey = ?", - into(mDBId), into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(privkey), into(email_checked), into(language_key), - use(pubkey); - try { - auto result = select.execute(); - if (result == 1) { - mState = USER_LOADED_FROM_DB; - mLanguage = LanguageManager::languageFromString(language_key); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - if (email_checked == 0) { mState = USER_EMAIL_NOT_ACTIVATED; } - else if (privkey.isNull()) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE; } - - mEmailChecked = email_checked == 1; - - size_t hexSize = pubkey.size() * 2 + 1; - char* hexString = (char*)malloc(hexSize); - memset(hexString, 0, hexSize); - sodium_bin2hex(hexString, hexSize, pubkey.content().data(), pubkey.size()); - mPublicHex = hexString; - free(hexString); - - if (!privkey.isNull()) { - auto privkey_value = privkey.value(); - auto privkey_size = privkey_value.size(); - //mPrivateKey = new ObfusArray(privkey_value.size(), privkey_value.content().data()); - mPrivateKey = MemoryManager::getInstance()->getFreeMemory(privkey_size); - memcpy(*mPrivateKey, privkey_value.content().data(), privkey_size); - } - - } - - } - catch (Poco::Exception& ex) { - addError(new ParamError("User::User", "mysql error", ex.displayText().data())); - } -} - -User::User(Poco::AutoPtr ctrl_user) - : mUserCtrl(ctrl_user), mState(USER_EMPTY), mDBId(0), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - assert(!ctrl_user.isNull()); - auto model = ctrl_user->getModel(); - assert(model); - - auto mm = MemoryManager::getInstance(); - mDBId = model->getID(); - mEmail = model->getEmail(); - mFirstName = model->getFirstName(); - mLastName = model->getLastName(); - mPasswordHashed = model->getPasswordHashed(); - auto pubkey = model->getPublicKey(); - if (pubkey) { - memcpy(mPublicKey, pubkey, crypto_sign_PUBLICKEYBYTES); - - size_t hexSize = crypto_sign_PUBLICKEYBYTES * 2 + 1; - auto hexStringTemp = mm->getFreeMemory(hexSize); - //char* hexString = (char*)malloc(hexSize); - memset(*hexStringTemp, 0, hexSize); - sodium_bin2hex((char*)(*hexStringTemp), hexSize, pubkey, crypto_sign_PUBLICKEYBYTES); - mPublicHex = std::string((char*)(*hexStringTemp)); - mm->releaseMemory(hexStringTemp); - } - if (model->hasPrivateKeyEncrypted()) { - auto privKeyVetor = model->getPrivateKeyEncrypted(); - mPrivateKey = mm->getFreeMemory(privKeyVetor.size()); - memcpy(*mPrivateKey, privKeyVetor.data(), privKeyVetor.size()); - } - mEmailChecked = model->isEmailChecked(); - mLanguage = LanguageManager::languageFromString(model->getLanguageKey()); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - /* - USER_EMPTY, - USER_LOADED_FROM_DB, - USER_PASSWORD_INCORRECT, - USER_PASSWORD_ENCRYPTION_IN_PROCESS, - USER_EMAIL_NOT_ACTIVATED, - USER_NO_KEYS, - USER_NO_PRIVATE_KEY, - USER_COMPLETE - */ - - if (mEmail != "") { - mState = USER_LOADED_FROM_DB; - - if (!mEmailChecked) { mState = USER_EMAIL_NOT_ACTIVATED; } - else if (!pubkey) { mState = USER_NO_KEYS; } - else if (!mPrivateKey) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE; } - } -} - - -User::~User() -{ -#ifdef DEBUG_USER_DELETE_ENV - printf("[User::~User]\n"); -#endif - auto mm = MemoryManager::getInstance(); - if (mCryptoKey) { - //delete mCryptoKey; - mm->releaseMemory(mCryptoKey); - mCryptoKey = nullptr; - } - if (mPrivateKey) { - //delete mPrivateKey; - mm->releaseMemory(mPrivateKey); - mPrivateKey = nullptr; - } -} - -void User::setLanguage(Languages lang) -{ - lock("User::setLanguage"); - if (mLanguage != lang) { - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(lang); - } - mLanguage = lang; - unlock(); -} - - -std::string User::generateNewPassphrase(Mnemonic* word_source) -{ - auto em = ErrorManager::getInstance(); - static const char* errorMessageForUser = "Ein Fehler, bitte wende dich an den Server-Admin (coin@gradido.net). | An error occured, please ask the server admin (coin@gradido.net)."; - unsigned int random_indices[PHRASE_WORD_COUNT]; - unsigned int str_sizes[PHRASE_WORD_COUNT]; - unsigned int phrase_buffer_size = 0; - bool errorReloadingMnemonicWordList = false; - int loopTrys = 0; - Poco::RegularExpression checkValidWord("^[a-zA-ZÄÖÜäöüß&;]*$"); - - // TODO: make sure words didn't double - for (int i = 0; i < PHRASE_WORD_COUNT; i++) { - random_indices[i] = randombytes_random() % 2048; - auto word = word_source->getWord(random_indices[i]); - if (loopTrys > 10 || errorReloadingMnemonicWordList) { - return errorMessageForUser; - } - if (!word) { - em->addError(new ParamError("User::generateNewPassphrase", "empty word get for index", random_indices[i])); - em->sendErrorsAsEmail(); - - random_indices[i] = randombytes_random() % 2048; - word = word_source->getWord(random_indices[i]); - if (!word) return errorMessageForUser; - - } - else { - if (!checkValidWord.match(word, 0, Poco::RegularExpression::RE_NOTEMPTY)) { - em->addError(new ParamError("User::generateNewPassphrase", "invalid word", word)); - em->addError(new Error("User::generateNewPassphrase", "try to reload mnemonic word list, but this error is maybe evidence for a serious memory problem!!!")); - if (!ServerConfig::loadMnemonicWordLists()) { - em->addError(new Error("User::generateNewPassphrase", "error reloading mnemonic word lists")); - errorReloadingMnemonicWordList = true; - } - else { - i = 0; - loopTrys++; - } - em->sendErrorsAsEmail(); - //return "Server Fehler, bitte frage den Admin coin@gradido.net | Server error, please ask the admin coin@gradido.net"; - } - } - str_sizes[i] = strlen(word); - phrase_buffer_size += str_sizes[i]; - } - phrase_buffer_size += PHRASE_WORD_COUNT + 1; - - std::string phrase_buffer(phrase_buffer_size, '\0'); - int phrase_buffer_cursor = 0; - - for (int i = 0; i < PHRASE_WORD_COUNT; i++) { - memcpy(&phrase_buffer[phrase_buffer_cursor], word_source->getWord(random_indices[i]), str_sizes[i]); - - phrase_buffer_cursor += str_sizes[i]; - phrase_buffer[phrase_buffer_cursor++] = ' '; - } - - - return phrase_buffer; -} - -bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/) -{ - return KeyPair::validatePassphrase(passphrase, wordSource); - -} - -bool User::isEmptyPassword() -{ - bool bRet = false; - lock("User::isEmptyPassword"); - //printf("[User::isEmptyPassword] pwd hashed: %d, running: %d, this: %d\n", -// mPasswordHashed, !mCreateCryptoKeyTask.isNull(), this); - bRet = mPasswordHashed == 0 && (mCreateCryptoKeyTask.isNull() || mCreateCryptoKeyTask->isTaskFinished()); - unlock(); - return bRet; -} - -UserStates User::getUserState() -{ - UserStates state; - lock("User::getUserState"); - state = mState; - unlock(); - return state; -} - -Poco::JSON::Object User::getJson() -{ - lock("User::getJson"); - Poco::JSON::Object userObj; - - userObj.set("first_name", mFirstName); - userObj.set("last_name", mLastName); - userObj.set("email", mEmail); - userObj.set("public_hex", mPublicHex); - userObj.set("state", userStateToString(mState)); - userObj.set("email_checked", mEmailChecked); - userObj.set("ident_hash", DRMakeStringHash(mEmail.data(), mEmail.size())); - unlock(); - return userObj; -} - -/* -// TODO: if a password and privkey already exist, load current private key and re encrypt with new crypto key -bool User::setNewPassword(const std::string& newPassword) -{ - //Profiler timeUsed; - if (newPassword == "") { - lock("User::setNewPassword"); - addError(new Error("Passwort", "Ist leer.")); - unlock(); - return false; - } - if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) { - lock("User::setNewPassword"); - addError(new Error("Passwort", "Wird bereits erstellt, bitte in ca. 1 minute neuladen.")); - unlock(); - return false; - } - duplicate(); - lock("User::setNewPassword"); - //printf("[User::setNewPassword] start create crypto key task with this: %d\n", this); - mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newPassword, ServerConfig::g_CPUScheduler); - mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask); - unlock(); - - duplicate(); - - UniLib::controller::TaskPtr savePassword(new UserWriteCryptoKeyHashIntoDB(this, 1)); - savePassword->setParentTaskPtrInArray(mCreateCryptoKeyTask, 0); - savePassword->scheduleTask(savePassword); - - - //printf("[User::setNewPassword] timeUsed: %s\n", timeUsed.string().data()); - return true; -} -*/ -bool User::updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser) -{ - static const char* functionName("User::updatePassword"); - if (newPassword == "") { - lock(functionName); - addError(new Error(gettext("Passwort"), gettext("Ist leer."))); - unlock(); - return false; - } - if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) { - lock(functionName); - addError(new Error(gettext("Passwort"), gettext("Wird bereits erstellt, bitte in ca. 1 minute neuladen."))); - unlock(); - return false; - } - //duplicate(); - //lock("User::setNewPassword"); - //printf("[User::setNewPassword] start create crypto key task with this: %d\n", this); - //mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newPassword, ServerConfig::g_CPUScheduler); - //mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask); - //unlock(); - - auto mm = MemoryManager::getInstance(); - - bool passwordHashedCalculated = false; - - // no previous password set - - //if (!mPasswordHashed) { - duplicate(); - lock(functionName); - //printf("[User::setNewPassword] start create crypto key task with this: %d\n", this); - mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newUser, newPassword, ServerConfig::g_CPUScheduler); - mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask); - unlock(); - //} - /*else { - // compare with previous password - auto cryptoKey = createCryptoKey(newPassword); - auto passwordHash = createPasswordHashed(cryptoKey); - lock(functionName); - if (mPasswordHashed == passwordHash) { - addError(new Error(gettext("Passwort"), gettext("Du hast dasselbe Passwort gewählt, bitte wähle ein anderes."))); - unlock(); - mm->releaseMemory(cryptoKey); - return false; - } - mPasswordHashed = passwordHash; - passwordHashedCalculated = true; - if (mCryptoKey) { - mm->releaseMemory(mCryptoKey); - } - mCryptoKey = cryptoKey; - unlock(); - }*/ - - duplicate(); - UniLib::controller::TaskPtr savePassword(nullptr); - UserWriteCryptoKeyHashIntoDB* writePWDHashedIntoDB = nullptr; - if (passwordHashedCalculated) { - savePassword = new UserWriteCryptoKeyHashIntoDB(this, 0); - } - else { - savePassword = new UserWriteCryptoKeyHashIntoDB(this, 1); - savePassword->setParentTaskPtrInArray(mCreateCryptoKeyTask, 0); - } - savePassword->scheduleTask(savePassword); - - if (passphrase != "") { - duplicate(); - UniLib::controller::TaskPtr genKeys(new UserGenerateKeys(this, newUser, passphrase)); - genKeys->scheduleTask(genKeys); - - - std::vector saveKeysParents; - saveKeysParents.reserve(2); // to prevent allocating more memory as ever needed - saveKeysParents.push_back(genKeys); - if (!passwordHashedCalculated) { - saveKeysParents.push_back(mCreateCryptoKeyTask); - } - duplicate(); - UniLib::controller::TaskPtr saveKeys(new UserWriteKeysIntoDB(saveKeysParents, this, true)); - saveKeys->scheduleTask(saveKeys); - } - - //printf("[User::setNewPassword] timeUsed: %s\n", timeUsed.string().data()); - return true; -} - -void User::setEmailChecked() -{ - lock("User::setEmailChecked"); - mEmailChecked = true; - if (mState <= USER_EMAIL_NOT_ACTIVATED) { - if (mPublicHex == "") { - mState = USER_NO_KEYS; - } - else if (!mPrivateKey) { - mState = USER_NO_PRIVATE_KEY; - } - else { - mState = USER_COMPLETE; - } - } - unlock(); -} - -bool User::validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint) -{ - auto mm = MemoryManager::getInstance(); - auto cmpCryptoKey = createCryptoKey(pwd); - if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { - throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); - } - if (nullptr == cmpCryptoKey) { - if (validationErrorsToPrint) { - validationErrorsToPrint->addError(new Error("User::validatePwd", "couldn't create crypto key")); - return false; - } - } - User::passwordHashed pwdHashed; - if (!ServerConfig::g_ServerCryptoKey) { - if (validationErrorsToPrint) { - validationErrorsToPrint->addError(new Error("User::validatePwd", "server crypto key not set")); - } - mm->releaseMemory(cmpCryptoKey); - return false; - } - crypto_shorthash((unsigned char*)&pwdHashed, *cmpCryptoKey, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey); - lock("User::validatePwd"); - if (pwdHashed == mPasswordHashed) { - if (!mCryptoKey) { - mCryptoKey = cmpCryptoKey; - } - else { - //delete cmpCryptoKey; - mm->releaseMemory(cmpCryptoKey); - } - unlock(); - return true; - } - //delete cmpCryptoKey; - mm->releaseMemory(cmpCryptoKey); - - unlock(); - return false; -} - -void User::login(Poco::AutoPtr newUser) -{ - assert(!newUser.isNull()); - assert(newUser->getModel()); - - lock("User::validatePwd"); - mPasswordHashed = newUser->getModel()->getPasswordHashed(); - auto mm = MemoryManager::getInstance(); - if (mCryptoKey) { - mm->releaseMemory(mCryptoKey); - mCryptoKey = nullptr; - } - auto keyPair = newUser->getGradidoKeyPair(); - if (keyPair) { - mCryptoKey = keyPair->getCryptedPrivKey(newUser->getPassword()); - } - unlock(); -} - -bool User::validateIdentHash(HASH hash) -{ - lock("User::validateIdentHash"); - HASH local_hash = DRMakeStringHash(mEmail.data(), mEmail.size()); - unlock(); - return local_hash == hash; -} - -bool User::deleteFromDB() -{ - auto cm = ConnectionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - Poco::Data::Statement deleteFromDB(session); - //DELETE FROM `table_name` [WHERE condition]; - - std::string tables[] = { "users", "email_opt_in", "user_backups" }; - - /*deleteFromDB - << "DELETE from users where id = ?;" - "DELETE from email_opt_in where user_id = ?;" - "DELETE from user_backups where user_id = ?", - use(mDBId), use(mDBId), use(mDBId); - */ - for (int i = 0; i < 3; i++) { - if (i > 0) { - deleteFromDB.reset(session); - deleteFromDB << "DELETE from " << tables[i] << " where user_id = ?", use(mDBId); - } - else { - deleteFromDB << "DELETE from " << tables[i] << " where id = ?", use(mDBId); - } - - try { - lock("User::deleteFromDB"); - auto result = deleteFromDB.execute(); - unlock(); - //printf("[User::deleteFromDB] %s deleted: %d\n", tables[i].data(), result); - } - catch (Poco::Exception& ex) { - unlock(); - em->addError(new ParamError("[User::deleteFromDB]", "error deleting user tables", ex.displayText().data())); - em->sendErrorsAsEmail(); - //return false; - } - } - - - return true; -} - -void User::duplicate() -{ - Poco::Mutex::ScopedLock _lock(mReferenceMutex); - //mReferenceMutex.lock(); - mReferenceCount++; -#ifdef DEBUG_USER_DELETE_ENV - printf("[User::duplicate] new value: %d\n", mReferenceCount); -#endif - //mReferenceMutex.unlock(); -} - -void User::release() -{ - - Poco::Mutex::ScopedLock _lock(mReferenceMutex); - //mReferenceMutex.lock(); - mReferenceCount--; -#ifdef DEBUG_USER_DELETE_ENV - printf("[User::release] new value: %d, this: %d\n", mReferenceCount, this); -#endif - if (0 == mReferenceCount) { - //mReferenceMutex.unlock(); - delete this; - return; - } - //mReferenceMutex.unlock(); - -} - -MemoryBin* User::createCryptoKey(const std::string& password) -{ - - //Profiler timeUsed; - auto mm = MemoryManager::getInstance(); - auto observer = SingletonTaskObserver::getInstance(); - static const char* funcName = "User::createCryptoKey"; - if (mEmail == "") { - lock(funcName); - addError(new Error(funcName, "email is empty")); - unlock(); - return nullptr; - } - - - - // TODO: put it in secure location, or use value from server config - static const unsigned char app_secret[] = { 0x21, 0xff, 0xbb, 0xc6, 0x16, 0xfe }; - - sha_context context_sha512; - //unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE); - if (SHA_512_SIZE < crypto_pwhash_SALTBYTES) { - lock(funcName); - addError(new Error(funcName, "sha512 is to small for libsodium pwhash saltbytes")); - unlock(); - return nullptr; - } - - observer->addTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION); - - unsigned char hash512_salt[SHA_512_SIZE]; // need at least crypto_pwhash_SALTBYTES 16U - sha512_init(&context_sha512); - sha512_update(&context_sha512, (const unsigned char*)mEmail.data(), mEmail.size()); - sha512_update(&context_sha512, app_secret, 6); - sha512_final(&context_sha512, hash512_salt); - - - //unsigned char* key = (unsigned char *)malloc(crypto_box_SEEDBYTES); // 32U - //ObfusArray* key = new ObfusArray(crypto_box_SEEDBYTES); - auto key = mm->getFreeMemory(crypto_box_SEEDBYTES); - //Bin32Bytes* key = mm->get32Bytes(); - if (crypto_pwhash(*key, key->size(), password.data(), password.size(), hash512_salt, 10U, 33554432, 2) != 0) { - lock(funcName); - addError(new ParamError(funcName, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno))); - unlock(); - observer->removeTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION); - //printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno)); - //printf("pwd: %s\n", pwd); - return nullptr; - } - observer->removeTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION); - -// lock(); -// auto cryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key); -// unlock(); -// free(key); - - // mCryptoKey - //printf("[User::createCryptoKey] time used: %s\n", timeUsed.string().data()); - return key; -} - -User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver/* = nullptr*/) -{ - if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { - throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); - } - User::passwordHashed pwdHashed = 0; - if (!ServerConfig::g_ServerCryptoKey) { - if (errorReceiver) { - errorReceiver->addError(new Error("User::validatePwd", "server crypto key not set")); - } - return pwdHashed; - } - crypto_shorthash((unsigned char*)&pwdHashed, *cryptoKey, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey); - - return pwdHashed; -} - -void User::fakeCreateCryptoKey() -{ - Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime); -} - -bool User::generateKeys(bool savePrivkey, const std::string& passphrase, Session* session) -{ - //Profiler timeUsed; - - duplicate(); - UniLib::controller::TaskPtr generateKeysTask(new UserGenerateKeys(this, session->getNewUser(), passphrase)); - //generateKeysTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_KEY_PAIR_GENERATED, session)); - //generateKeysTask->scheduleTask(generateKeysTask); - // run directly because we like to show pubkey on interface, shouldn't last to long - generateKeysTask->run(); - session->updateState(SESSION_STATE_KEY_PAIR_GENERATED); - - if (mDBId == 0) { - //printf("[User::generateKeys] dbid is zero, load from db\n"); - loadEntryDBId(ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); - if (mDBId == 0) { - auto em = ErrorManager::getInstance(); - em->addError(new ParamError("User::generateKeys", "user not found in db with email", mEmail.data())); - em->sendErrorsAsEmail(); - } - return false; - } - - duplicate(); - std::vector parentsForWriteKeys; - parentsForWriteKeys.reserve(2); - parentsForWriteKeys.push_back(generateKeysTask); - if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) { - parentsForWriteKeys.push_back(mCreateCryptoKeyTask); - } - - UniLib::controller::TaskPtr saveKeysTask(new UserWriteKeysIntoDB(parentsForWriteKeys, this, savePrivkey)); - saveKeysTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_KEY_PAIR_WRITTEN, session)); - saveKeysTask->scheduleTask(saveKeysTask); - - -// printf("[User::generateKeys] call two tasks, time used: %s\n", timeUsed.string().data()); - return true; - -} - -MemoryBin* User::encrypt(const MemoryBin* data) -{ - if (!hasCryptoKey()) { - addError(new Error("User::encrypt", "hasn't crypto key")); - return nullptr; - } - if (!data) { - addError(new Error("User::encrypt", "data is zero")); - return nullptr; - } - size_t message_len = data->size(); - size_t ciphertext_len = crypto_secretbox_MACBYTES + message_len; - - unsigned char nonce[crypto_secretbox_NONCEBYTES]; - // we use a hardcoded value for nonce - memset(nonce, 31, crypto_secretbox_NONCEBYTES); - - //unsigned char* ciphertext = (unsigned char*)malloc(ciphertext_len); - //ObfusArray* ciphertext = new ObfusArray(ciphertext_len); - auto mm = MemoryManager::getInstance(); - auto ciphertext = mm->getFreeMemory(ciphertext_len); - memset(*ciphertext, 0, ciphertext_len); - - if (0 != crypto_secretbox_easy(*ciphertext, *data, message_len, nonce, *mCryptoKey)) { - //printf("[%s] error encrypting message \n", __FUNCTION__); - addError(new Error("User::encrypt", "encrypting message failed")); - //free(ciphertext); - mm->releaseMemory(ciphertext); - - return nullptr; - } - - //printf("[User::encrypt] encrypted: %s, ciphertext len: %u\n", KeyPair::getHex(ciphertext, ciphertext_len).data(), ciphertext_len); - - //auto resultObfus = new ObfusArray(ciphertext_len, ciphertext); - //free(ciphertext); - - return ciphertext; -} - -MemoryBin* User::decrypt(const MemoryBin* encryptedData) -{ - if (!hasCryptoKey()) { - addError(new Error("User::decrypt", "hasn't crypto key")); - return nullptr; - } - //printf("[User::decrypt] decrypt: %s, ciphertext len: %u\n", KeyPair::getHex(*encryptedData, encryptedData->size()).data(), encryptedData->size()); - //ObfusArray* decrypetData = new ObfusArray(encryptedData->size() - crypto_secretbox_MACBYTES); - - size_t decryptSize = encryptedData->size() - crypto_secretbox_MACBYTES; - //unsigned char* decryptBuffer = (unsigned char*)malloc(decryptSize); - auto mm = MemoryManager::getInstance(); - //ObfusArray* decryptedData = new ObfusArray(decryptSize); - auto decryptedData = mm->getFreeMemory(decryptSize); - unsigned char nonce[crypto_secretbox_NONCEBYTES]; - // we use a hardcoded value for nonce - memset(nonce, 31, crypto_secretbox_NONCEBYTES); - - if (crypto_secretbox_open_easy(*decryptedData, *encryptedData, encryptedData->size(), nonce, *mCryptoKey)) { - mm->releaseMemory(decryptedData); - addError(new Error("User::decrypt", "error decrypting")); - return nullptr; - } - /*int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, - unsigned long long clen, const unsigned char *n, - const unsigned char *k);*/ - - return decryptedData; -} - -MemoryBin* User::sign(const unsigned char* message, size_t messageSize) -{ - - if (!message || !messageSize) return nullptr; - if (!hasCryptoKey()) { - addError(new Error("User::sign", "hasn't crypto key")); - return nullptr; - } - if (!mPrivateKey) { - addError(new Error("User::sign", "hasn't privkey")); - return nullptr; - } - - //binArrayObj = new BinaryArray(crypto_sign_BYTES); - auto mm = MemoryManager::getInstance(); - //auto signBinBuffer = (unsigned char*)malloc(crypto_sign_BYTES); - auto privKey = getPrivKey(); - - if (!privKey) { - //addError(new Error("User::sign", "decrypt privkey failed")); - - - auto userBackups = controller::UserBackup::load(mDBId); - - // get privkey, only possible while passphrase isn't crypted in db - bool correctPassphraseFound = false; - KeyPair keys; - for (auto it = userBackups.begin(); it != userBackups.end(); it++) { - - auto passphrase = (*it)->getModel()->getPassphrase(); - Mnemonic* wordSource = nullptr; - if (User::validatePassphrase(passphrase, &wordSource)) { - if (keys.generateFromPassphrase((*it)->getModel()->getPassphrase().data(), wordSource)) { - if(keys.isPubkeysTheSame(getPublicKey())) - { - correctPassphraseFound = true; - break; - } - } - } - } - if (correctPassphraseFound) { - - // save corrected key into db - auto encyrptedPrivKey = encrypt(keys.getPrivateKey()); - auto newUser = controller::User::create(); - if (1 == newUser->load(mDBId)) { - auto userModel = newUser->getModel(); - if (encyrptedPrivKey) { - userModel->setPrivateKey(encyrptedPrivKey); - userModel->updatePrivkey(); - // remove unencrypt error from priv key to prevent error 404 forwarding - delete getLastError(); - } - - mm->releaseMemory(encyrptedPrivKey); - - } - - // sign with received key - auto const_privKey = keys.getPrivateKey(); - auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES); - unsigned long long actualSignLength = 0; - - if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *const_privKey)) { - addError(new Error("User::sign 2", "sign failed")); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) { - // Incorrect signature! - //printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__); - addError(new Error("User::sign 2", "sign verify failed")); - mm->releaseMemory(privKey); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - return signBinBuffer; - } - - return nullptr; - } - - auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES); - - unsigned long long actualSignLength = 0; - - if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *privKey)) { - addError(new Error("User::sign", "sign failed")); - mm->releaseMemory(privKey); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) { - // Incorrect signature! - //printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__); - addError(new Error("User::sign", "sign verify failed")); - mm->releaseMemory(privKey); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - // debug - const size_t hex_sig_size = crypto_sign_BYTES * 2 + 1; - char sig_hex[hex_sig_size]; - sodium_bin2hex(sig_hex, hex_sig_size, *signBinBuffer, crypto_sign_BYTES); - printf("[User::sign] signature hex: %s\n", sig_hex); - - mm->releaseMemory(privKey); - - return signBinBuffer; -} - -Poco::Data::Statement User::insertIntoDB(Poco::Data::Session session) -{ - - Poco::Data::Statement insert(session); - - //Poco::Data::BLOB pwd(&mPasswordHashed[0], crypto_shorthash_BYTES); - - //printf("[User::insertIntoDB] password hashed: %llu\n", mPasswordHashed); - std::string languageKey = LanguageManager::keyForLanguage(mLanguage); - if (mPasswordHashed) { - insert << "INSERT INTO users (email, first_name, last_name, password, language) VALUES(?, ?, ?, ?, ?);", - use(mEmail), use(mFirstName), use(mLastName), bind(mPasswordHashed), bind(languageKey); - } - else { - insert << "INSERT INTO users (email, first_name, last_name, language) VALUES(?, ?, ?, ?);", - use(mEmail), use(mFirstName), use(mLastName), bind(languageKey); - } - - - return insert; -} - -bool User::updateIntoDB(UserFields fieldType) -{ - - if (mDBId == 0) { - addError(new Error("User::updateIntoDB", "user id is zero")); - return false; - } - if (USER_FIELDS_PASSWORD == fieldType || USER_FIELDS_EMAIL_CHECKED == fieldType) { - auto session = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement update(session); - if (USER_FIELDS_PASSWORD == fieldType) { - update << "UPDATE users SET password = ? where id = ?", - use(mPasswordHashed), use(mDBId); - } - else if (USER_FIELDS_EMAIL_CHECKED == fieldType) { - update << "UPDATE users SET email_checked = ? where id = ?", - use(mEmailChecked), use(mDBId); - } - else if (USER_FIELDS_LANGUAGE == fieldType) { - std::string languageKey = LanguageManager::keyForLanguage(mLanguage); - update << "UPDATE users SET language = ? where id = ?", - bind(languageKey), use(mDBId); - } - try { - if (update.execute() == 1) return true; - addError(new ParamError("User::updateIntoDB", "update not affected 1 rows", fieldType)); - } - catch (Poco::Exception& ex) { - auto em = ErrorManager::getInstance(); - em->addError(new ParamError("User::updateIntoDB", "mysql error", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - } - - return false; - -} - -bool User::loadEntryDBId(Poco::Data::Session session) -{ - auto em = ErrorManager::getInstance(); - Poco::Data::Statement select(session); - - select << "SELECT id from users where email = ?;", - into(mDBId), use(mEmail); - try { - if (select.execute() != 1) { - addError(new Error("User::loadEntryDBId", "didn't get expectet row count (1)")); - return false; - } - } catch(Poco::Exception& ex) { - em->addError(new ParamError("[User::loadEntryDBId]", "error selecting from db", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - - return true; -} - -const char* User::userStateToString(UserStates state) -{ - switch (state) { - case USER_EMPTY: return "empty"; - case USER_LOADED_FROM_DB: return "loaded from db"; - case USER_PASSWORD_INCORRECT: return "password incorrect"; - case USER_EMAIL_NOT_ACTIVATED: return "email not activated"; - case USER_NO_KEYS: return "no keys"; - case USER_NO_PRIVATE_KEY: return "no private key"; - case USER_COMPLETE: return "complete"; - } - return "- unknown -"; -} - -MemoryBin* User::getPrivKey() -{ - if (!mPrivateKey) { - addError(new Error("User::getPrivKey", "no private key saved")); - return nullptr; - } - if (!hasCryptoKey()) { - addError(new Error("User::getPrivKey", "no crypto key set for decrypting priv key")); - return nullptr; - } - return decrypt(mPrivateKey); -} - -bool User::setPrivKey(const MemoryBin* privKey) -{ - if (!hasCryptoKey()) { - lock("User::setPrivKey"); - addError(new Error("User::getPrivKey", "no crypto key set for encrypting priv key")); - unlock(); - return false; - } - auto encyrptedPrivKey = encrypt(privKey); - lock("User::setPrivKey"); - mState = USER_COMPLETE; - mPrivateKey = encyrptedPrivKey;// encrypt(privKey); - unlock(); - - return true; -} - -void User::lock(const char* stateInfos/* = nullptr*/) -{ - try { - mWorkingMutex.lock(500); - } - catch (Poco::TimeoutException& ex) { - addError(new ParamError("User::lock", "timeout exception", ex.displayText())); - if (stateInfos) { - addError(new ParamError("User::lock", "stateInfos", stateInfos)); - } - sendErrorsAsEmail(); - } -} \ No newline at end of file diff --git a/src/cpp/model/User.h b/src/cpp/model/User.h deleted file mode 100644 index cc1a8be86..000000000 --- a/src/cpp/model/User.h +++ /dev/null @@ -1,272 +0,0 @@ -#ifndef GRADIDO_LOGIN_SERVER_MODEL_USER_INCLUDE -#define GRADIDO_LOGIN_SERVER_MODEL_USER_INCLUDE - -#include "../Crypto/KeyPair.h" -#include -//#include "ModelBase.h" -#include "../lib/NotificationList.h" - -#include "Poco/Thread.h" -#include "Poco/Types.h" -#include "Poco/Data/Session.h" -#include "Poco/JSON/Object.h" -#include "../tasks/CPUTask.h" - -#include "../SingletonManager/MemoryManager.h" -#include "../SingletonManager/LanguageManager.h" - -#include "../controller/User.h" - -class UserCreateCryptoKey; -class UserWriteIntoDB; -class Session; -class UserWriteCryptoKeyHashIntoDB; -class SigningTransaction; -class UserGenerateKeys; -class DebugPassphrasePage; -class RepairDefectPassphrase; - -enum UserStates -{ - USER_EMPTY, - USER_LOADED_FROM_DB, - USER_PASSWORD_INCORRECT, - USER_PASSWORD_ENCRYPTION_IN_PROCESS, - USER_EMAIL_NOT_ACTIVATED, - USER_NO_KEYS, - USER_NO_PRIVATE_KEY, - USER_KEYS_DONT_MATCH, - USER_COMPLETE, - USER_DISABLED -}; - -enum UserFields -{ - USER_FIELDS_ID, - USER_FIELDS_FIRST_NAME, - USER_FIELDS_LAST_NAME, - USER_FIELDS_PASSWORD, - USER_FIELDS_EMAIL_CHECKED, - USER_FIELDS_LANGUAGE -}; - -class User : public NotificationList -{ - friend UserCreateCryptoKey; - friend UserWriteIntoDB; - friend UserWriteCryptoKeyHashIntoDB; - friend SigningTransaction; - friend UserGenerateKeys; - friend DebugPassphrasePage; - friend RepairDefectPassphrase; -public: - // new user - User(const char* email, const char* first_name, const char* last_name); - // existing user - User(const char* email); - - // existing user by public key - User(const unsigned char* pubkey_array); - - User(int user_id); - - // load from controller user - User(Poco::AutoPtr ctrl_user); - - // login - //User(const std::string& email, const std::string& password); - - ~User(); - - void login(Poco::AutoPtr newUser); - - static std::string generateNewPassphrase(Mnemonic* word_source); - static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr); - static const char* userStateToString(UserStates state); - //static User* login(const std::string& email, const std::string& password, ErrorList* errorContainer = nullptr); - - bool generateKeys(bool savePrivkey, const std::string& passphrase, Session* session); - - bool loadEntryDBId(Poco::Data::Session session); - - bool deleteFromDB(); - - inline bool hasCryptoKey() { lock(); bool bRet = mCryptoKey != nullptr; unlock(); return bRet; } - - inline const char* getEmail() const { return mEmail.data(); } - inline const char* getFirstName() const { return mFirstName.data(); } - inline const char* getLastName() const { return mLastName.data(); } - inline int getDBId() const { return mDBId; } - inline int getBalance() { lock(); int balance = mGradidoCurrentBalance; unlock(); return balance; } - inline std::string getPublicKeyHex() { lock(); std::string pubkeyHex = mPublicHex; unlock(); return pubkeyHex; } - inline const unsigned char* getPublicKey() { return mPublicKey; } - inline Languages getLanguage() { lock(); Languages lang = mLanguage; unlock(); return lang; } - - inline void setPublicKeyHex(const std::string& publicKeyHex) { lock(); mPublicHex = publicKeyHex; unlock(); } - inline void setPublicKey(const unsigned char* key) { lock(); memcpy(mPublicKey, key, crypto_sign_PUBLICKEYBYTES); unlock();} - - inline const char* gettext(const char* text) { if (mLanguageCatalog.isNull()) return text; return mLanguageCatalog->gettext(text); } - - UserStates getUserState(); - - void setLanguage(Languages lang); - inline void setBalance(int balance) { lock(); mGradidoCurrentBalance = balance; unlock(); } - void setEmailChecked(); - bool isEmptyPassword(); - //bool setNewPassword(const std::string& newPassword); - bool updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser); - bool validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint); - bool validateIdentHash(HASH hash); - - MemoryBin* encrypt(const MemoryBin* data); - MemoryBin* decrypt(const MemoryBin* encryptedData); - MemoryBin* sign(const unsigned char* message, size_t messageSize); - - Poco::JSON::Object getJson(); - - // for poco auto ptr - void duplicate(); - void release(); - - //! \brief wait time create crypto key is normally running - static void fakeCreateCryptoKey(); -protected: - typedef Poco::UInt64 passwordHashed; - - MemoryBin* createCryptoKey(const std::string& password); - static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver = nullptr); - inline void setCryptoKey(MemoryBin* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); } - - //void detectState(); - - Poco::Data::Statement insertIntoDB(Poco::Data::Session session); - bool updateIntoDB(UserFields fieldType); - inline passwordHashed getPwdHashed() { lock(); auto ret = mPasswordHashed; unlock(); return ret; } - inline void setPwdHashed(passwordHashed pwdHashed) { lock(); mPasswordHashed = pwdHashed; unlock(); } - - void lock(const char* stateInfos = nullptr); - inline void unlock() { mWorkingMutex.unlock(); } - - MemoryBin* getPrivKey(); - inline bool hasPrivKey() { lock(); bool result = false; if (mPrivateKey && mCryptoKey) result = true; unlock(); return result; } - bool setPrivKey(const MemoryBin* privKey); - -private: - Poco::AutoPtr mUserCtrl; - UserStates mState; - - // ************************* DB FIELDS ****************************** - int mDBId; - std::string mEmail; - std::string mFirstName; - std::string mLastName; - - passwordHashed mPasswordHashed; - - std::string mPublicHex; - unsigned char mPublicKey[crypto_sign_PUBLICKEYBYTES]; - //! crypted private key - MemoryBin* mPrivateKey; - // TODO: insert created if necessary - - bool mEmailChecked; - Languages mLanguage; - - // ************************ DB FIELDS END ****************************** - - int mGradidoCurrentBalance; - Poco::AutoPtr mLanguageCatalog; - - // crypto key as obfus array - // only in memory, if user has typed in password - MemoryBin* mCryptoKey; - - Poco::Mutex mWorkingMutex; - Poco::Mutex mReferenceMutex; - - // for poco auto ptr - int mReferenceCount; - - UniLib::controller::TaskPtr mCreateCryptoKeyTask; -}; - -class UserCreateCryptoKey : public UniLib::controller::CPUTask -{ -public: - UserCreateCryptoKey(Poco::AutoPtr user, Poco::AutoPtr newUser, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler); - - virtual int run(); - virtual const char* getResourceType() const { return "UserCreateCryptoKey"; }; - -private: - Poco::AutoPtr mUser; - Poco::AutoPtr mNewUser; - std::string mPassword; -}; - -class UserGenerateKeys : public UniLib::controller::CPUTask -{ -public: - UserGenerateKeys(Poco::AutoPtr user, Poco::AutoPtr newUser, const std::string& passphrase) - : mUser(user), mNewUser(newUser), mPassphrase(passphrase) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - ~UserGenerateKeys() { - - } - virtual int run(); - inline KeyPair* getKeyPairs() { return &mKeys; } - - virtual const char* getResourceType() const { return "UserGenerateKeys"; }; -protected: - Poco::AutoPtr mUser; - Poco::AutoPtr mNewUser; - std::string mPassphrase; - KeyPair mKeys; -}; - -class UserWriteIntoDB : public UniLib::controller::CPUTask -{ -public: - UserWriteIntoDB(Poco::AutoPtr user, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) - : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - virtual int run(); - virtual const char* getResourceType() const { return "UserWriteIntoDB"; }; -private: - Poco::AutoPtr mUser; -}; - -class UserWriteKeysIntoDB : public UniLib::controller::CPUTask -{ -public: - UserWriteKeysIntoDB(std::vector parents, Poco::AutoPtr user, bool savePrivKey); - - virtual int run(); - - virtual const char* getResourceType() const { return "UserWriteKeysIntoDB"; }; -protected: - Poco::AutoPtr mUser; - bool mSavePrivKey; -}; - -class UserWriteCryptoKeyHashIntoDB : public UniLib::controller::CPUTask -{ -public: - UserWriteCryptoKeyHashIntoDB(Poco::AutoPtr user, int dependencieCount = 0); - - int run(); - const char* getResourceType() const { return "UserWriteCryptoKeyHashIntoDB"; }; - -protected: - Poco::AutoPtr mUser; -}; - -#endif //GRADIDO_LOGIN_SERVER_MODEL_USER_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index 11584659c..d45147532 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -17,8 +17,8 @@ namespace model { { } - User::User(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) - : mFirstName(first_name), mLastName(last_name), mPasswordHashed(passwordHashed), mEmailChecked(false), mLanguageKey(languageKey), mDisabled(false), mRole(ROLE_NOT_LOADED) + User::User(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) + : mFirstName(first_name), mLastName(last_name), mPasswordHashed(passwordHashed), mEmailChecked(false), mLanguageKey(languageKey), mDisabled(false), mGroupId(group_id), mRole(ROLE_NOT_LOADED) { setEmail(email); @@ -27,7 +27,7 @@ namespace model { User::User(UserTuple tuple) : ModelBase(tuple.get<0>()), mFirstName(tuple.get<1>()), mLastName(tuple.get<2>()), mEmail(tuple.get<3>()), - mPublicKey(tuple.get<4>()), mCreated(tuple.get<5>()), mEmailChecked(tuple.get<6>()), mDisabled(tuple.get<7>()), + mPublicKey(tuple.get<4>()), mCreated(tuple.get<5>()), mEmailChecked(tuple.get<6>()), mDisabled(tuple.get<7>()), mGroupId(tuple.get<8>()), mPasswordHashed(0), mLanguageKey("de"), mRole(ROLE_NOT_LOADED) { @@ -80,12 +80,12 @@ namespace model { if (mPasswordHashed) { - insert << "INSERT INTO users (email, first_name, last_name, password, email_hash, language) VALUES(?,?,?,?,?,?);", - use(mEmail), use(mFirstName), use(mLastName), bind(mPasswordHashed), use(mEmailHash), use(mLanguageKey); + insert << "INSERT INTO users (email, first_name, last_name, password, email_hash, language, group_id) VALUES(?,?,?,?,?,?,?);", + use(mEmail), use(mFirstName), use(mLastName), bind(mPasswordHashed), use(mEmailHash), use(mLanguageKey), use(mGroupId); } else { - insert << "INSERT INTO users (email, first_name, last_name, email_hash, language) VALUES(?,?,?,?,?);", - use(mEmail), use(mFirstName), use(mLastName), use(mEmailHash), use(mLanguageKey); + insert << "INSERT INTO users (email, first_name, last_name, email_hash, language, group_id) VALUES(?,?,?,?,?,?);", + use(mEmail), use(mFirstName), use(mLastName), use(mEmailHash), use(mLanguageKey), use(mGroupId); } return insert; @@ -98,13 +98,13 @@ namespace model { _fieldName = getTableName() + std::string(".id"); } Poco::Data::Statement select(session); - select << "SELECT " << getTableName() << ".id, email, first_name, last_name, password, pubkey, privkey, email_hash, created, email_checked, language, disabled, user_roles.role_id " + select << "SELECT " << getTableName() << ".id, email, first_name, last_name, password, pubkey, privkey, email_hash, created, email_checked, language, disabled, group_id, user_roles.role_id " << " FROM " << getTableName() << " LEFT JOIN user_roles ON " << getTableName() << ".id = user_roles.user_id " << " WHERE " << _fieldName << " = ?" , into(mID), into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(mPublicKey), into(mPrivateKey), into(mEmailHash), into(mCreated), into(mEmailChecked), - into(mLanguageKey), into(mDisabled), into(mRole); + into(mLanguageKey), into(mDisabled), into(mGroupId), into(mRole); return select; @@ -114,7 +114,7 @@ namespace model { { Poco::Data::Statement select(session); // typedef Poco::Tuple, int> UserTuple; - select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled FROM " << getTableName() + select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled, group_id FROM " << getTableName() << " where " << fieldName << " LIKE ?"; @@ -130,7 +130,7 @@ namespace model { } // typedef Poco::Tuple, int> UserTuple; - select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled FROM " << getTableName() + select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled, group_id FROM " << getTableName() << " where " << fieldNames[0] << " LIKE ?"; if (conditionType == MYSQL_CONDITION_AND) { for (int i = 1; i < fieldNames.size(); i++) { @@ -311,6 +311,7 @@ namespace model { ss << "email checked: " << mEmailChecked << std::endl; ss << "language key: " << mLanguageKey << std::endl; ss << "disabled: " << mDisabled << std::endl; + ss << "group id: " << std::to_string(mGroupId) << std::endl; mm->releaseMemory(pubkeyHex); mm->releaseMemory(privkeyHex); @@ -346,6 +347,7 @@ namespace model { ss << "language key: " << mLanguageKey << "
    "; ss << "role: " << UserRole::typeToString(getRole()) << "
    "; ss << "disabled: " << mDisabled << "
    "; + ss << "group_id: " << std::to_string(mGroupId) << std::endl; mm->releaseMemory(pubkeyHex); mm->releaseMemory(email_hash); @@ -369,6 +371,25 @@ namespace model { return pubkeyHexString; } + std::string User::getPrivateKeyEncryptedHex() const + { + std::shared_lock _lock(mSharedMutex); + auto mm = MemoryManager::getInstance(); + std::string privkeyHexString; + + if (!mPrivateKey.isNull()) { + auto priv_key_size = mPrivateKey.value().content().size(); + auto privkeyHex = mm->getFreeMemory(priv_key_size+1); + + memset(*privkeyHex, 0, priv_key_size+1); + sodium_bin2hex(*privkeyHex, 65, mPrivateKey.value().content().data(), priv_key_size); + privkeyHexString = std::string((const char*)privkeyHex->data(), privkeyHex->size() - 1); + mm->releaseMemory(privkeyHex); + } + + return privkeyHexString; + } + Poco::JSON::Object User::getJson() { diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index 9d95a3223..d4fb2ea87 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -29,14 +29,16 @@ namespace model { USER_FIELDS_LANGUAGE }; - typedef Poco::Tuple, Poco::DateTime, int, int> UserTuple; + typedef Poco::Tuple, Poco::DateTime, int, int, int> UserTuple; class User : public ModelBase { public: +#define SHARED_LOCK std::shared_lock _lock(mSharedMutex) +#define UNIQUE_LOCK std::unique_lock _lock(mSharedMutex) User(); User(UserTuple tuple); - User(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); + User(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); ~User(); // generic db operations @@ -54,35 +56,38 @@ namespace model { size_t updateFieldsFromCommunityServer(); // default getter unlocked - inline const std::string getEmail() const { std::shared_lock _lock(mSharedMutex); return mEmail; } - inline const std::string getFirstName() const { std::shared_lock _lock(mSharedMutex); return mFirstName; } - inline const std::string getLastName() const { std::shared_lock _lock(mSharedMutex); return mLastName; } - inline std::string getNameWithEmailHtml() const { std::shared_lock _lock(mSharedMutex); return mFirstName + " " + mLastName + " <" + mEmail + ">"; } - inline const Poco::UInt64 getPasswordHashed() const { std::shared_lock _lock(mSharedMutex); return mPasswordHashed; } - inline RoleType getRole() const { std::shared_lock _lock(mSharedMutex); if (mRole.isNull()) return ROLE_NONE; return static_cast(mRole.value()); } - inline const unsigned char* getPublicKey() const { std::shared_lock _lock(mSharedMutex); if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } - inline size_t getPublicKeySize() const { std::shared_lock _lock(mSharedMutex); if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } + inline const std::string getEmail() const { SHARED_LOCK; return mEmail; } + inline const std::string getFirstName() const { SHARED_LOCK; return mFirstName; } + inline const std::string getLastName() const { SHARED_LOCK; return mLastName; } + inline std::string getNameWithEmailHtml() const { SHARED_LOCK; return mFirstName + " " + mLastName + " <" + mEmail + ">"; } + inline const Poco::UInt64 getPasswordHashed() const { SHARED_LOCK; return mPasswordHashed; } + inline RoleType getRole() const { SHARED_LOCK; if (mRole.isNull()) return ROLE_NONE; return static_cast(mRole.value()); } + inline const unsigned char* getPublicKey() const { SHARED_LOCK; if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + inline size_t getPublicKeySize() const { SHARED_LOCK; if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } std::string getPublicKeyHex() const; + std::string getPrivateKeyEncryptedHex() const; - inline bool hasPrivateKeyEncrypted() const { std::shared_lock _lock(mSharedMutex); return !mPrivateKey.isNull(); } - inline bool hasEmailHash() const { std::shared_lock _lock(mSharedMutex); return !mEmailHash.isNull(); } - inline const std::vector& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); } - inline bool isEmailChecked() const { std::shared_lock _lock(mSharedMutex); return mEmailChecked; } - inline const std::string getLanguageKey() const { std::shared_lock _lock(mSharedMutex); return mLanguageKey; } - inline bool isDisabled() const { std::shared_lock _lock(mSharedMutex); return mDisabled; } + inline bool hasPrivateKeyEncrypted() const { SHARED_LOCK; return !mPrivateKey.isNull(); } + inline bool hasPublicKey() const { SHARED_LOCK; return !mPublicKey.isNull(); } + inline bool hasEmailHash() const { SHARED_LOCK; return !mEmailHash.isNull(); } + inline const std::vector& getPrivateKeyEncrypted() const { SHARED_LOCK; return mPrivateKey.value().content(); } + inline bool isEmailChecked() const { SHARED_LOCK; return mEmailChecked; } + inline const std::string getLanguageKey() const { SHARED_LOCK; return mLanguageKey; } + inline bool isDisabled() const { SHARED_LOCK; return mDisabled; } + inline int getGroupId() const { SHARED_LOCK; return mGroupId; } // default setter unlocked void setEmail(const std::string& email); - inline void setFirstName(const std::string& first_name) { std::unique_lock _lock(mSharedMutex); mFirstName = first_name; } - inline void setLastName(const std::string& last_name) { std::unique_lock _lock(mSharedMutex); mLastName = last_name; } - inline void setPasswordHashed(const Poco::UInt64& passwordHashed) { std::unique_lock _lock(mSharedMutex); mPasswordHashed = passwordHashed; } + inline void setFirstName(const std::string& first_name) { UNIQUE_LOCK; mFirstName = first_name; } + inline void setLastName(const std::string& last_name) { UNIQUE_LOCK; mLastName = last_name; } + inline void setPasswordHashed(const Poco::UInt64& passwordHashed) { UNIQUE_LOCK; mPasswordHashed = passwordHashed; } void setPublicKey(const unsigned char* publicKey); //! \brief set encrypted private key //! \param privateKey copy data, didn't move memory bin void setPrivateKey(const MemoryBin* privateKey); - inline void setEmailChecked(bool emailChecked) { std::unique_lock _lock(mSharedMutex); mEmailChecked = emailChecked; } - inline void setLanguageKey(const std::string& languageKey) { std::unique_lock _lock(mSharedMutex); mLanguageKey = languageKey; } - inline void setDisabled(bool disabled) { std::unique_lock _lock(mSharedMutex); mDisabled = disabled; } + inline void setEmailChecked(bool emailChecked) { UNIQUE_LOCK; mEmailChecked = emailChecked; } + inline void setLanguageKey(const std::string& languageKey) { UNIQUE_LOCK; mLanguageKey = languageKey; } + inline void setDisabled(bool disabled) { UNIQUE_LOCK; mDisabled = disabled; } Poco::JSON::Object getJson(); @@ -113,6 +118,8 @@ namespace model { //! if set to true, prevent login bool mDisabled; + int mGroupId; + // from neighbor tables Poco::Nullable mRole; diff --git a/src/cpp/tasks/SigningTransaction.h b/src/cpp/tasks/SigningTransaction.h index aaaeb9253..e3b659edd 100644 --- a/src/cpp/tasks/SigningTransaction.h +++ b/src/cpp/tasks/SigningTransaction.h @@ -5,7 +5,6 @@ #include "../lib/NotificationList.h" #include "../model/TransactionBase.h" -#include "../model/User.h" #include "../controller/User.h" #include "../proto/gradido/GradidoTransaction.pb.h" diff --git a/src/cpsp/Error500.cpsp b/src/cpsp/Error500.cpsp index 7cea4f563..0cc255eed 100644 --- a/src/cpsp/Error500.cpsp +++ b/src/cpsp/Error500.cpsp @@ -10,18 +10,18 @@ <% const char* pageName = "Error"; response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR); - Poco::AutoPtr user; + Poco::AutoPtr user; if(mSession) { - auto user = mSession->getUser(); + auto user = mSession->getNewUser(); } %><%@ include file="header_old.cpsp" %>

    Ein Fehler auf dem Server trat ein, der Admin bekam eine E-Mail.

    <% if(mSession) { %> - <%= mSession->getErrorsHtml() %> + <%= mSession->getErrorsHtmlNewFormat() %> <% } %> <% if(!user.isNull()) {%> - <%= user->getErrorsHtml() %> + <%= user->getModel()->getErrorsHtmlNewFormat() %> <% } %>
    <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/PassphrasedTransaction.cpsp b/src/cpsp/PassphrasedTransaction.cpsp index debc1f296..8c360da79 100644 --- a/src/cpsp/PassphrasedTransaction.cpsp +++ b/src/cpsp/PassphrasedTransaction.cpsp @@ -6,7 +6,7 @@ <%! #include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/SessionManager.h" -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" #include "Poco/JSON/Object.h" @@ -23,29 +23,28 @@ enum PageState { <%% std::string pageName = "Gradidos mit Passphrase überweisen"; PageState state = PAGE_STATE_INPUT; - Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]; + Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES]; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); std::string errorString =""; if(!form.empty()) { auto passphrase = form.get("passphrase", ""); - bool passphraseValid = User::validatePassphrase(passphrase, &wordSource); + auto passphrase_obj = Passphrase::create(passphrase, wordSource); + bool keysGenerated = false; - KeyPair keys; - if(!passphraseValid) - { + KeyPairEd25519* keys = nullptr; + if(!passphrase_obj.isNull()) { addError(new Error("Passphrase", "Fehler beim validieren der Passphrase")); } - else - { - keysGenerated = keys.generateFromPassphrase(passphrase.data(), wordSource); - if(!keysGenerated) + else { + keys = KeyPairEd25519::create(passphrase_obj); + if(!keys) { addError(new Error("Passphrase", "Konnte keine Keys aus der Passphrase generieren")); } } - if(passphraseValid && keysGenerated) + if(keys) { // create session only for transaction int session_id = 0; @@ -53,7 +52,7 @@ enum PageState { // create payload Poco::JSON::Object requestJson; Poco::JSON::Object pubkeys; - pubkeys.set("sender", keys.getPubkeyHex()); + pubkeys.set("sender", keys->getPublicKeyHex()); pubkeys.set("receiver", form.get("recevier", "")); requestJson.set("method", "moveTransaction"); requestJson.set("pubkeys", pubkeys); @@ -129,6 +128,8 @@ enum PageState { if(session) { sm->releaseSession(session); } + delete keys; + keys = nullptr; } } diff --git a/src/cpsp/adminCheckUserBackup.cpsp b/src/cpsp/adminCheckUserBackup.cpsp index 35ac38ad4..66156796d 100644 --- a/src/cpsp/adminCheckUserBackup.cpsp +++ b/src/cpsp/adminCheckUserBackup.cpsp @@ -5,10 +5,11 @@ <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> <%! -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" +#include "../Crypto/Passphrase.h" #include "../SingletonManager/ConnectionManager.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "Poco/Data/Binding.h" using namespace Poco::Data::Keywords; @@ -25,7 +26,7 @@ struct SListEntry <%% const char* pageName = "Admin Check User Backups"; auto cm = ConnectionManager::getInstance(); - KeyPair keys; + std::list notMatchingEntrys; auto con = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); @@ -44,21 +45,24 @@ struct SListEntry if(pubkey.isNull()) { continue; } - auto passphrase = KeyPair::filterPassphrase(tuple.get<2>()); + auto passphrase = Passphrase::filter(tuple.get<2>()); auto user_id = tuple.get<0>(); - Mnemonic* wordSource = nullptr; - if(!User::validatePassphrase(passphrase, &wordSource)) { + KeyPairEd25519 key_pair(pubkey.value().content().data()); + + auto wordSource = Passphrase::detectMnemonic(passphrase); + if(!wordSource) { addError(new Error("admin Check user backup", "invalid passphrase"), false); addError(new ParamError("admin Check user backup", "passphrase", passphrase.data()), false); addError(new ParamError("admin Check user backup", "user id", user_id), false); continue; - } else { - keys.generateFromPassphrase(passphrase.data(), wordSource); - } + } + auto passphrase_object = Passphrase::create(passphrase, wordSource); + auto key_pair_from_passhrase = KeyPairEd25519::create(passphrase_object); bool matching = false; - if(keys.isPubkeysTheSame(pubkey.value().content().data())) { + if(key_pair_from_passhrase->isTheSame(key_pair)) { matching = true; } + delete key_pair_from_passhrase; if(user_id != last_user_id) { last_user_id = user_id; if(matching) continue; diff --git a/src/cpsp/adminUserPasswordReset.cpsp b/src/cpsp/adminUserPasswordReset.cpsp index f534b8c4d..7022b42d9 100644 --- a/src/cpsp/adminUserPasswordReset.cpsp +++ b/src/cpsp/adminUserPasswordReset.cpsp @@ -8,7 +8,7 @@ // includes #include "../controller/User.h" #include "../controller/EmailVerificationCode.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" enum PageState @@ -47,11 +47,11 @@ enum PageState } } - auto backups = controller::UserBackups::load(userId); + auto backups = controller::UserBackup::load(userId); auto userPubkey = user->getModel()->getPublicKey(); for(auto it = backups.begin(); it != backups.end(); it++) { auto keys = (*it)->getKeyPair(); - if(keys->isPubkeysTheSame(userPubkey)) { + if(keys->isTheSame(userPubkey)) { userBackup = *it; break; } @@ -102,7 +102,7 @@ enum PageState hier findest du deine Passphrase mit dessen Hilfe du dir ein neues Passwort einstellen kannst. Bitte schreibe sie dir auf und packe sie gut weg. -<%= controller::UserBackups::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) %> +<%= controller::UserBackup::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) %> diff --git a/src/cpsp/checkTransaction.cpsp b/src/cpsp/checkTransaction.cpsp index 77d61a1ba..ef121dcb4 100644 --- a/src/cpsp/checkTransaction.cpsp +++ b/src/cpsp/checkTransaction.cpsp @@ -163,8 +163,10 @@ enum PageState { <%= gettext("Gradido") %>
    - <% if(transactionUser) { %> - <%= transactionUser->getFirstName() %> <%= transactionUser->getLastName() %> <<%= transactionUser->getEmail() %>> + <% if(!transactionUser.isNull()) { + auto user_model = transactionUser->getModel(); + %> + <%= user_model->getFirstName() %> <%= user_model->getLastName() %> <<%= user_model->getEmail() %>> <% } else { %> 0x<%= creationTransaction->getPublicHex() %> <% } %> diff --git a/src/cpsp/dashboard.cpsp b/src/cpsp/dashboard.cpsp index 687c6a709..654f7a4c3 100644 --- a/src/cpsp/dashboard.cpsp +++ b/src/cpsp/dashboard.cpsp @@ -10,6 +10,8 @@ %> <%% const char* pageName = "Dashboard"; + auto user = mSession->getNewUser(); + auto user_model = user->getModel(); //Poco::Net::NameValueCollection cookies; //request.getCookies(cookies); if(!form.empty()) { @@ -20,7 +22,7 @@ return; %><%@ include file="header_old.cpsp" %>
    -

    Willkommen <%= mSession->getUser()->getFirstName() %> <%= mSession->getUser()->getLastName() %>

    +

    Willkommen <%= user_model->getFirstName() %> <%= user_model->getLastName() %>

    <%= mSession->getErrorsHtml() %>

    Status

    <%= mSession->getSessionStateString() %>

    diff --git a/src/cpsp/debugMnemonic.cpsp b/src/cpsp/debugMnemonic.cpsp index 06f0c5f86..aa52d4561 100644 --- a/src/cpsp/debugMnemonic.cpsp +++ b/src/cpsp/debugMnemonic.cpsp @@ -6,7 +6,7 @@ <%@ header include="SessionHTTPRequestHandler.h" %> <%! #include "../ServerConfig.h" -#include "../Crypto/KeyPair.h" +#include "../Crypto/Passphrase.h" struct WordChecked { WordChecked() : index(0), bSet(false) {}; @@ -48,7 +48,7 @@ { if("" != form.get("check_word", "")) { - auto word = KeyPair::filterPassphrase(form.get("word", "")); + auto word = Passphrase::filter(form.get("word", "")); if("" != word) { checkedWord.bSet = true; checkedWord.word = word; diff --git a/src/cpsp/debugPassphrase.cpsp b/src/cpsp/debugPassphrase.cpsp index 936a4629f..416bdf0a3 100644 --- a/src/cpsp/debugPassphrase.cpsp +++ b/src/cpsp/debugPassphrase.cpsp @@ -5,45 +5,36 @@ <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> <%! -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" +#include "../controller/User.h" %> <%% const char* pageName = "Debug Passphrase"; - auto mm = MemoryManager::getInstance(); - KeyPair keys; - std::string privKeyHex = ""; + + KeyPairEd25519* keys = nullptr; std::string privKeyCryptedHex = ""; - User::passwordHashed pwdHashed = 0; + Poco::UInt64 pwdHashed = 0; Poco::AutoPtr existingUser; if(!form.empty()) { - auto passphrase = KeyPair::filterPassphrase(form.get("passphrase", "")); - Mnemonic* wordSource = nullptr; - if(!User::validatePassphrase(passphrase, &wordSource)) { + auto passphrase_string = form.get("passphrase", ""); + auto wordSource = Passphrase::detectMnemonic(passphrase_string); + if(!wordSource) { addError(new Error("debug Passphrase", "invalid passphrase"), false); } else { - keys.generateFromPassphrase(passphrase.data(), wordSource); + keys = KeyPairEd25519::create(Passphrase::create(passphrase_string, wordSource)); } auto email = form.get("email", ""); - auto newUser = new User(email.data(), "first_name", "last_name"); - if(email != "") { existingUser = controller::User::create(); - existingUser->load(email); - } - newUser->validatePwd(form.get("password", ""), this); - pwdHashed = newUser->getPwdHashed(); - auto privKey = keys.getPrivateKey(); - if(privKey) { - privKeyHex = KeyPair::getHex(privKey); - auto privKeyCrypted = newUser->encrypt(privKey); - if(privKeyCrypted) { - privKeyCryptedHex = KeyPair::getHex(privKeyCrypted); - mm->releaseMemory(privKeyCrypted); + if(1 == existingUser->load(email)) { + auto user_model = existingUser->getModel(); + pwdHashed = user_model->getPasswordHashed(); + if(user_model->hasPrivateKeyEncrypted()) { + privKeyCryptedHex = user_model->getPrivateKeyEncryptedHex(); + } } } - getErrors(newUser); - delete newUser; } @@ -58,23 +49,21 @@ "/>

    -

    - - -

    -

    Public key:
    <%= keys.getPubkeyHex() %>

    -

    Private Key:
    <%= privKeyHex %>

    -

    Passwort Hashed:
    <%= std::to_string(pwdHashed) %>

    -

    Private key crypted:
    <%= privKeyCryptedHex %>

    - <% if(!existingUser.isNull()) { - auto userModel = existingUser->getModel(); - auto dbPubkey = userModel->getPublicKey(); - %> -

    user Public:
    <%= KeyPair::getHex(dbPubkey, ed25519_pubkey_SIZE) %>

    + <% if(keys) { %> +

    Public key:
    <%= keys->getPublicKeyHex() %>

    +

    Private key crypted:
    <%= privKeyCryptedHex %>

    +

    Passwort Hashed:
    <%= std::to_string(pwdHashed) %>

    + <% if(!existingUser.isNull()) { + auto userModel = existingUser->getModel(); + auto dbPubkey = userModel->getPublicKey(); + %> +

    user Public:
    <%= keys->getPublicKeyHex() %>

    + <% } %> <% } %>
    +<% if(keys) delete keys; %> <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index 70018bc79..fa9b4258b 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -26,8 +26,8 @@ auto langCatalog = lm->getFreeCatalog(lang); std::string presetEmail(""); - if(mSession && mSession->getUser()) { - presetEmail = mSession->getUser()->getEmail(); + if(mSession && mSession->getNewUser()) { + presetEmail = mSession->getNewUser()->getModel()->getEmail(); } if(!form.empty()) { @@ -114,6 +114,9 @@ } sm->deleteLoginCookies(request, response); break; + case USER_NO_GROUP: + response.redirect(ServerConfig::g_serverPath + "/userUpdateGroup"); + return; case USER_NO_PRIVATE_KEY: case USER_COMPLETE: case USER_EMAIL_NOT_ACTIVATED: diff --git a/src/cpsp/passphrase.cpsp b/src/cpsp/passphrase.cpsp index d941bffcd..e8079fec9 100644 --- a/src/cpsp/passphrase.cpsp +++ b/src/cpsp/passphrase.cpsp @@ -7,7 +7,7 @@ <%! #include "../SingletonManager/SessionManager.h" #include "../SingletonManager/LanguageManager.h" -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" //#include "Poco/Net/HTTPServerParams.h" @@ -68,13 +68,15 @@ enum PageState auto registerKeyChoice = form.get("passphrase", "no"); std::string oldPassphrase = ""; if (registerKeyChoice == "no") { - auto oldPassphrase = KeyPair::filterPassphrase(form.get("passphrase-existing", "")); + auto oldPassphrase = Passphrase::filter(form.get("passphrase-existing", "")); if(oldPassphrase != "") { - if (User::validatePassphrase(oldPassphrase, &wordSource)) { + auto word_source = Passphrase::detectMnemonic(oldPassphrase); + if (word_source) { // passphrase is valid if(PAGE_FORCE_ASK_PASSPHRASE == state) { - auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, wordSource); + + auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, word_source); if(-2 == compareResult) { response.redirect(ServerConfig::g_serverPath + "/error500"); return; @@ -96,7 +98,8 @@ enum PageState } } else if (registerKeyChoice == "yes") { - mSession->generatePassphrase(); + auto passphrase = Passphrase::generate(wordSource); + mSession->setPassphrase(passphrase); } } } @@ -104,7 +107,7 @@ enum PageState // double check passphrase auto passphrase = mSession->getOldPassphrase(); auto langWordSource = wordSource; - if("" != passphrase && !User::validatePassphrase(passphrase, &wordSource)) { + if("" != passphrase && !Passphrase::detectMnemonic(passphrase)) { addError(new Error("PassphrasePage", "Invalid Passphrase after double check")); addError(new ParamError("PassphrasePage", "passphrase", passphrase.data())); if(!mSession->getNewUser().isNull()) { @@ -117,8 +120,8 @@ enum PageState } //printf("wordSource: %d, langWordSource: %d\n", (int)wordSource, (int)langWordSource); if(wordSource != langWordSource) { - mSession->generatePassphrase(); - User::validatePassphrase(passphrase, &wordSource); + //mSession->generatePassphrase(); + mSession->setPassphrase(Passphrase::generate(wordSource)); } if(mSession->getSessionState() == SESSION_STATE_PASSPHRASE_GENERATED && state != PAGE_ASK_ENSURE_PASSPHRASE) { @@ -160,7 +163,7 @@ enum PageState
    <%= gettext("Deine Passphrase (Groß/Kleinschreibung beachten)") %>:
    -

    <%= mSession->getPassphrase() %>

    +

    <%= mSession->getPassphrase()->getString() %>

    <%= gettext("Was zu tun ist:") %>
    @@ -212,7 +215,7 @@ enum PageState
    diff --git a/src/cpsp/registerAdmin.cpsp b/src/cpsp/registerAdmin.cpsp index 6f1db5b76..495de5a14 100644 --- a/src/cpsp/registerAdmin.cpsp +++ b/src/cpsp/registerAdmin.cpsp @@ -6,22 +6,41 @@ <%@ header include="SessionHTTPRequestHandler.h" %> <%! #include "../SingletonManager/SessionManager.h" +#include "../controller/Group.h" +#include "../lib/DataTypeConverter.h" + #include "Poco/Net/HTTPCookie.h" + %> <%% const char* pageName = "Admin Registrieren"; - //auto sm = SessionManager::getInstance(); + auto sm = SessionManager::getInstance(); bool userReturned = false; if(!form.empty()) { - userReturned = mSession->adminCreateUser( - form.get("register-first-name", ""), - form.get("register-last-name", ""), - form.get("register-email", "") - ); - getErrors(mSession); + auto group_id_string = form.get("register-group", "0"); + int group_id = 0; + if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } + if(!errorCount()) { + userReturned = mSession->adminCreateUser( + form.get("register-first-name", ""), + form.get("register-last-name", ""), + form.get("register-email", ""), + group_id + ); + getErrors(mSession); + } + } + + auto groups = controller::Group::listAll(); %><%@ include file="header_old.cpsp" %> @@ -52,6 +71,12 @@ "/>

    + diff --git a/src/cpsp/registerDirect.cpsp b/src/cpsp/registerDirect.cpsp index 6eadb19dc..f6c3dc49a 100644 --- a/src/cpsp/registerDirect.cpsp +++ b/src/cpsp/registerDirect.cpsp @@ -5,7 +5,10 @@ <%@ header include="PageRequestMessagedHandler.h" %> <%! #include "../SingletonManager/SessionManager.h" +#include "../controller/Group.h" +#include "../lib/DataTypeConverter.h" #include "Poco/Net/HTTPCookie.h" + %> <%% const char* pageName = "Registrieren"; @@ -24,12 +27,22 @@ session->setClientIp(user_host); response.addCookie(session->getLoginCookie()); } + auto group_id_string = form.get("register-group", "0"); + int group_id = 0; + if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } userReturned = session->createUserDirect( form.get("register-first-name", ""), form.get("register-last-name", ""), form.get("register-email", ""), - form.get("register-password", "") + form.get("register-password", ""), + group_id ); getErrors(session); @@ -48,6 +61,9 @@ // remove old cookies if exist sm->deleteLoginCookies(request, response); } + + auto groups = controller::Group::listAll(); + %><%@ include file="header.cpsp" %> <%= getErrorsHtml() %>
    @@ -67,6 +83,13 @@ +
    diff --git a/src/cpsp/saveKeys.cpsp b/src/cpsp/saveKeys.cpsp index 03fe1b763..d157ceaed 100644 --- a/src/cpsp/saveKeys.cpsp +++ b/src/cpsp/saveKeys.cpsp @@ -19,7 +19,8 @@ enum PageState const char* pageName = "Daten auf Server speichern?"; bool hasErrors = mSession->errorCount() > 0; // crypto key only in memory, if user has tipped in his passwort in this session - bool hasPassword = mSession->getUser()->hasCryptoKey(); + auto user = mSession->getNewUser(); + bool hasPassword = user->getModel()->hasPrivateKeyEncrypted(); PageState state = PAGE_ASK; auto uri_start = ServerConfig::g_php_serverPath;//request.serverParams().getServerName(); @@ -123,7 +124,7 @@ enum PageState Zurück zur Startseite
    diff --git a/src/cpsp/translatePassphrase.cpsp b/src/cpsp/translatePassphrase.cpsp index ad22a8e90..f8dd20a6a 100644 --- a/src/cpsp/translatePassphrase.cpsp +++ b/src/cpsp/translatePassphrase.cpsp @@ -5,7 +5,7 @@ <%@ page form="true" %> <%@ page compressed="true" %> <%! -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" %> <%% @@ -29,16 +29,17 @@ { inputPassphrase = form.get("inputPassphrase", ""); - auto localPassphrase = KeyPair::filterPassphrase(inputPassphrase); + auto localPassphrase = Passphrase::filter(inputPassphrase); auto btnGenerate = form.get("btnGenerate", ""); if("" != btnGenerate) { - mSession->generatePassphrase(); - localPassphrase = mSession->getOldPassphrase(); + auto passphrase_gen = Passphrase::generate(wordSource); + + localPassphrase = passphrase_gen->getString(); inputPassphrase = localPassphrase; } - - if(localPassphrase != "" && !User::validatePassphrase(localPassphrase, &wordSource)) { + auto passphrase_object = Passphrase::create(localPassphrase, wordSource); + if(localPassphrase != "" && passphrase_object.isNull() || !passphrase_object->checkIfValid()) { addError(new Error( gettext("Fehler"), gettext("Diese Passphrase ist ungültig, bitte überprüfen oder neu generieren (lassen).") @@ -49,7 +50,8 @@ } else { targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]; } - passphrase = KeyPair::passphraseTransform(localPassphrase, wordSource, targetSource); + auto transformed_passphrase_obj = passphrase_object->transform(targetSource); + passphrase = transformed_passphrase_obj->getString(); } diff --git a/src/cpsp/updateUser.cpsp b/src/cpsp/updateUser.cpsp deleted file mode 100644 index 43e3a311a..000000000 --- a/src/cpsp/updateUser.cpsp +++ /dev/null @@ -1,69 +0,0 @@ -<%@ page class="UpdateUserPage" %> -<%@ page form="true" %> -<%@ page baseClass="SessionHTTPRequestHandler" %> -<%@ page ctorArg="Session*" %> -<%@ header include="SessionHTTPRequestHandler.h" %> -<%@ page compressed="true" %> -<%! -#include "../SingletonManager/SessionManager.h" -#include "Poco/Net/HTTPCookie.h" -#include "../model/Profiler.h" -%> -<%% - const char* pageName = "Update"; - Profiler timeUsed; - auto user = mSession->getUser(); - - if(!form.empty()) { - auto pwd = form.get("update-password", ""); - if(pwd != "") { - if(pwd != form.get("update-password", "")) { - session->addError(new Error("Passwort", "Passwörter sind nicht identisch.")); - } else { - userReturned = session->getUser()->setNewPassword( - form.get("update-password") - ); - } - } - } -%><%@ include file="header.cpsp" %> -
    -

    Einen neuen Account anlegen

    - <% if(!form.empty()) {%> -
    -
    - .. -
    -
    - <% } else { %> -
    - - <% if(!form.empty() && !userReturned) {%> - <%= session->getErrorsHtml() %> - <%} %> -
    - Account anlegen -

    Bitte gebe deine Daten um einen Account anzulegen

    -

    - - "/> -

    -

    - - "/> -

    -

    - - -

    -

    - - -

    -
    - - -
    - <% } %> -
    -<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/userUpdateGroup.cpsp b/src/cpsp/userUpdateGroup.cpsp new file mode 100644 index 000000000..1fb1c4105 --- /dev/null +++ b/src/cpsp/userUpdateGroup.cpsp @@ -0,0 +1,62 @@ +<%@ page class="UserUpdateGroupPage" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%@ page compressed="true" %> +<%! + +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" + +enum PageState { + PAGE_STATE_OVERVIEW, + PAGE_STATE_REQUEST_IS_RUNNING +}; + +%> +<%% + const char* pageName = gettext("Gruppe wählen"); + auto user = mSession->getNewUser(); + auto sm = SessionManager::getInstance(); + PageState state = PAGE_STATE_OVERVIEW; + + if(!form.empty()) { + } + + auto groups = controller::Group::listAll(); + + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
    + <% if(PAGE_STATE_OVERVIEW == state ) { %> +
    +

    <%= gettext("Gruppe wählen") %>

    +
    +

    <%= gettext("Bitte wähle die Gruppe/Gemeinschaft aus, zu der du gehörst.") %>

    +

    <%= gettext("Du bekommst eine Bestätigungsmail, nachdem dein Beitritt bestätigt wurde.") %>

    +
    +
    +
    +
    <%= gettext("Auswahl") %>
    +
    Name
    +
    Alias
    +
    Url
    +
    <%= gettext("Description") %>
    +
    + <% for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); %> +
    +
    +
    <%= group_model->getName() %>
    +
    <%= group_model->getAlias() %>
    +
    <%= group_model->getUrl() %>
    +
    <%= group_model->getDescription()%>
    +
    + <% } %> + "/> +
    +
    + <% } %> +
    +<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/updateUserPassword.cpsp b/src/cpsp/userUpdatePassword.cpsp similarity index 98% rename from src/cpsp/updateUserPassword.cpsp rename to src/cpsp/userUpdatePassword.cpsp index 364b21c7f..0bb915a52 100644 --- a/src/cpsp/updateUserPassword.cpsp +++ b/src/cpsp/userUpdatePassword.cpsp @@ -1,4 +1,4 @@ -<%@ page class="UpdateUserPasswordPage" %> +<%@ page class="UserUpdatePasswordPage" %> <%@ page baseClass="SessionHTTPRequestHandler" %> <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> From 3f66cee0c9f3f731e11ee8106f75b6ff54b4e4f4 Mon Sep 17 00:00:00 2001 From: Dario via Pythagoras Date: Tue, 6 Oct 2020 11:46:39 +0200 Subject: [PATCH 040/195] changes in cmake, working in progess --- .gitmodules | 3 ++ CMakeLists.txt | 46 ++++++++++++++++++++++++++++-- dependencies/poco | 1 + src/cpp/Crypto/KeyPair.cpp | 12 ++++---- src/cpp/Crypto/KeyPairHedera.cpp | 6 ++-- src/cpp/controller/HederaAccount.h | 4 +-- src/proto | 2 +- 7 files changed, 59 insertions(+), 15 deletions(-) create mode 160000 dependencies/poco diff --git a/.gitmodules b/.gitmodules index 94115f227..7500d3d77 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "dependencies/grpc"] path = dependencies/grpc url = https://github.com/grpc/grpc.git +[submodule "dependencies/poco"] + path = dependencies/poco + url = https://github.com/pocoproject/poco.git diff --git a/CMakeLists.txt b/CMakeLists.txt index c8cbe2e74..ac13fb891 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories( "dependencies/spirit-po/include" "dependencies/grpc/include" "dependencies/grpc/third_party/protobuf/src" + #"dependencies/grpc/third_party/boringssl-with-bazel/src/include" "src/cpp/proto" #"dependencies/mariadb-connector-c/build/include" #"dependencies/mariadb-connector-c/include" @@ -22,6 +23,7 @@ include_directories( ) + FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h") FILE(GLOB HTTPInterface "src/cpp/HTTPInterface/*.h" "src/cpp/HTTPInterface/*.cpp") @@ -81,6 +83,7 @@ source_group("Test\\controller" FILES ${TEST_CONTROLLER}) source_group("Test" FILES ${TEST}) endif(MSVC) + include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() @@ -165,16 +168,38 @@ set(CMAKE_CXX_FLAGS "/MP /EHsc") #set(CMAKE_CXX_FLAGS_RELEASE "-O3") else(WIN32) +set(GRPC_BORING_SSL_PATH "dependencies/grpc/build/third_party/boringssl-with-bazel") +find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) +set(GRPC_LIBS + #${GRPC_BORING_SSL_CRYPTO} + #${GRPC_BORING_SSL_SSL} +) +#find_package(OpenSSL REQUIRED) +find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) +set(gRPC_SSL_PROVIDER "module") +find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) +find_package(Threads REQUIRED) +set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) + +#find_package(Poco REQUIRED) +#find_package(libsodium REQUIRED) +#find_package(gtest REQUIRED) find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) # set vars for mariadb cmake files set(INSTALL_BINDIR "bin") set(INSTALL_PLUGINDIR "bin") +OPTION(WITH_SSL "" OFF) add_subdirectory("dependencies/mariadb-connector-c") include_directories( "dependencies/mariadb-connector-c/include" "build/dependencies/mariadb-connector-c/include" + #${OpenSSL_INCLUDE_DIR} + #${Poco_INCLUDE_DIR} + #${libsodium_INCLUDE_DIR} + #${gtest_INCLUDE_DIR} ) @@ -183,13 +208,28 @@ endif(WIN32) add_subdirectory("dependencies/grpc/third_party/abseil-cpp") -target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) +#target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings)# ${CONAN_LIBS} ${IROHA_ED25519}) +message(STATUS "Conan libs: ") +list(REMOVE_ITEM CONAN_LIBS "ssl") +list(REMOVE_ITEM CONAN_LIBS "crypto") +foreach(i ${CONAN_LIBS}) + +message(STATUS ${i}) + +endforeach(i) + if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) -target_link_libraries(Gradido_LoginServer libmariadb protoc protobuf -pthread) +target_link_libraries(Gradido_LoginServer gRPC::grpc++) +target_link_libraries(Gradido_LoginServer ${CONAN_LIBS}) +target_link_libraries(Gradido_LoginServer libmariadb )# ${GRPC_LIBS} protoc protobuf pthread) +#target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) + + + endif(WIN32) # install @@ -220,7 +260,7 @@ if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) - target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf -pthread) + target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf pthread) endif(WIN32) add_test(NAME main COMMAND Gradido_LoginServer_Test) diff --git a/dependencies/poco b/dependencies/poco new file mode 160000 index 000000000..3fc3e5f5b --- /dev/null +++ b/dependencies/poco @@ -0,0 +1 @@ +Subproject commit 3fc3e5f5b8462f7666952b43381383a79b8b5d92 diff --git a/src/cpp/Crypto/KeyPair.cpp b/src/cpp/Crypto/KeyPair.cpp index 770f3dedf..9c6e3a22e 100644 --- a/src/cpp/Crypto/KeyPair.cpp +++ b/src/cpp/Crypto/KeyPair.cpp @@ -76,18 +76,18 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, const Mnemonic* wor createClearPassphraseFromWordIndices(word_indices, &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); // printf("clear passphrase: %s\n", clearPassphrase.data()); - sha_context state; + crypto_hash_sha512_state state; - unsigned char hash[SHA_512_SIZE]; + unsigned char hash[crypto_hash_sha512_BYTES]; //crypto_auth_hmacsha512_state state; size_t word_index_size = sizeof(word_indices); //crypto_auth_hmacsha512_init(&state, (unsigned char*)word_indices, sizeof(word_indices)); - sha512_init(&state); - sha512_update(&state, *word_indices, word_indices->size()); - sha512_update(&state, (unsigned char*)clearPassphrase.data(), clearPassphrase.size()); + crypto_hash_sha512_init(&state); + crypto_hash_sha512_update(&state, *word_indices, word_indices->size()); + crypto_hash_sha512_update(&state, (unsigned char*)clearPassphrase.data(), clearPassphrase.size()); //crypto_auth_hmacsha512_update(&state, (unsigned char*)passphrase, pass_phrase_size); - sha512_final(&state, hash); + crypto_hash_sha512_final(&state, hash); //crypto_auth_hmacsha512_final(&state, hash); /* diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index c2738e886..e16b76e05 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -44,7 +44,7 @@ KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeyS } break; default: - throw std::exception("[KeyPairHedera] invalid private key"); + throw Poco::Exception("[KeyPairHedera] invalid private key"); } // check public @@ -62,7 +62,7 @@ KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeyS } break; default: - throw std::exception("[KeyPairHedera] invalid public key"); + throw Poco::Exception("[KeyPairHedera] invalid public key"); } } auto public_key_2 = mm->getFreeMemory(ed25519_pubkey_SIZE); @@ -218,4 +218,4 @@ MemoryBin* KeyPairHedera::getPublicKeyCopy() const auto public_key = mm->getFreeMemory(ed25519_pubkey_SIZE); memcpy(*public_key, mPublicKey, ed25519_pubkey_SIZE); return public_key; -} \ No newline at end of file +} diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 709e84c7a..94e21a597 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -29,7 +29,7 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } - std::string HederaAccount::toShortSelectOptionName(); + std::string toShortSelectOptionName(); inline Poco::AutoPtr getModel() { return _getModel(); } inline const model::table::HederaAccount* getModel() const { return _getModel(); } @@ -53,4 +53,4 @@ namespace controller { }; } -#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE \ No newline at end of file +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE diff --git a/src/proto b/src/proto index 72e8fe7b7..81a461566 160000 --- a/src/proto +++ b/src/proto @@ -1 +1 @@ -Subproject commit 72e8fe7b73a1aaf2d057d2fef59ade9268830008 +Subproject commit 81a461566e46d71533dc3e284fa075d7d68fd020 From fdf15bb94825ccec3d52cfa2d5a4ddefb599f397 Mon Sep 17 00:00:00 2001 From: Dario via Pythagoras Date: Tue, 6 Oct 2020 12:03:25 +0200 Subject: [PATCH 041/195] add linux parse file --- unix_parse_proto.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 unix_parse_proto.sh diff --git a/unix_parse_proto.sh b/unix_parse_proto.sh new file mode 100755 index 000000000..3727cc985 --- /dev/null +++ b/unix_parse_proto.sh @@ -0,0 +1,19 @@ +#!/bin/bash +if [ ! -d "./src/cpp/proto" ] ; then + mkdir ./src/cpp/proto +fi +if [ ! -d "./src/cpp/proto/gradido" ] ; then + mkdir ./src/cpp/proto/gradido +fi +PROTOC_PATH=./dependencies/grpc/build/third_party/protobuf +CPP_PLUGIN_PATH=./dependencies/grpc/build +$PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto + +if [ ! -d "./src/cpp/proto/hedera" ] ; then + mkdir ./src/cpp/proto/hedera +fi + +GOOGLE_PROTOBUF_INCLUDES=./dependencies/grpc/third_party/protobuf/src +$PROTOC_PATH/protoc --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto + + From 2239d3c21b0e8f642e1276fbfc68e257c61a3222 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 6 Oct 2020 15:41:34 +0200 Subject: [PATCH 042/195] update code because irohe-ed25519 was removed --- src/cpp/Crypto/KeyPairHedera.cpp | 10 +++--- src/cpp/Crypto/KeyPairHedera.h | 5 ++- .../HTTPInterface/AdminHederaAccountPage.cpp | 2 +- .../HTTPInterface/RepairDefectPassphrase.cpp | 33 +++++++++---------- src/cpp/main.cpp | 4 +-- src/cpsp/adminHederaAccount.cpsp | 2 +- src/cpsp/repairDefectPassphrase.cpsp | 3 +- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index c2738e886..4a9220600 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -58,16 +58,16 @@ KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeyS } case 44: // DER encoded public key if (0 == sodium_memcmp(publicKey, *derPrefixPub, derPrefixPub->size())) { - memcpy(mPublicKey, &publicKey[derPrefixPub->size()], ed25519_pubkey_SIZE); + memcpy(mPublicKey, &publicKey[derPrefixPub->size()], crypto_sign_PUBLICKEYBYTES); } break; default: throw std::exception("[KeyPairHedera] invalid public key"); } } - auto public_key_2 = mm->getFreeMemory(ed25519_pubkey_SIZE); + auto public_key_2 = mm->getFreeMemory(crypto_sign_PUBLICKEYBYTES); crypto_sign_ed25519_sk_to_pk(*public_key_2, *mPrivateKey); - if (sodium_memcmp(*public_key_2, mPublicKey, ed25519_pubkey_SIZE) != 0) { + if (sodium_memcmp(*public_key_2, mPublicKey, crypto_sign_PUBLICKEYBYTES) != 0) { throw "public keys not match"; } @@ -215,7 +215,7 @@ MemoryBin* KeyPairHedera::getPrivateKeyCopy() const MemoryBin* KeyPairHedera::getPublicKeyCopy() const { auto mm = MemoryManager::getInstance(); - auto public_key = mm->getFreeMemory(ed25519_pubkey_SIZE); - memcpy(*public_key, mPublicKey, ed25519_pubkey_SIZE); + auto public_key = mm->getFreeMemory(crypto_sign_PUBLICKEYBYTES); + memcpy(*public_key, mPublicKey, crypto_sign_PUBLICKEYBYTES); return public_key; } \ No newline at end of file diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 769f29af6..b8dba9024 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -14,7 +14,6 @@ #include "sodium.h" #include "SecretKeyCryptography.h" -#include "iroha-ed25519/include/ed25519/ed25519.h" #include "../lib/DataTypeConverter.h" class KeyPairHedera : public IKeyPair @@ -43,7 +42,7 @@ public: inline const unsigned char* getPublicKey() const { return mPublicKey; } MemoryBin* getPublicKeyCopy() const; inline std::string getPublicKeyHex() const { return DataTypeConverter::binToHex(mPublicKey, getPublicKeySize()); } - const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;} + const static size_t getPublicKeySize() {return crypto_sign_PUBLICKEYBYTES;} inline bool isTheSame(const KeyPairHedera& b) const { return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, getPublicKeySize()); @@ -90,7 +89,7 @@ private: // 32 Byte //! \brief ed25519 libsodium public key - unsigned char mPublicKey[ed25519_pubkey_SIZE]; + unsigned char mPublicKey[crypto_sign_PUBLICKEYBYTES]; }; #endif //__GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H \ No newline at end of file diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 4bcf9b614..28c99c26a 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -202,7 +202,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), crypto_sign_PUBLICKEYBYTES); if(crypto_key.isNull()) { crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); diff --git a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp index 77fd06514..e089a38e2 100644 --- a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp +++ b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp @@ -9,7 +9,6 @@ #include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/EmailManager.h" -#include "../Crypto/KeyPair.h" #include "../Crypto/Passphrase.h" #include "../Crypto/KeyPairEd25519.h" #include "../lib/DataTypeConverter.h" @@ -53,7 +52,7 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 36 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 35 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" auto mm = MemoryManager::getInstance(); auto em = EmailManager::getInstance(); @@ -270,26 +269,26 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "
    \n"; // end include header_old.cpsp responseStream << "\n"; -#line 185 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" if("" != errorString) { responseStream << "\n"; responseStream << "\t"; -#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 185 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( errorString ); responseStream << "\n"; -#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t"; -#line 189 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 188 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\t

    Konto reparieren

    \n"; responseStream << "\t

    Der Login-Server hat festgestellt das die gespeicherte Passphrase nicht zu deinem Konto passt.

    \n"; responseStream << "\t"; -#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 191 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" if(GENERATE_PASSPHRASE == state) { responseStream << "\n"; responseStream << "\t\t"; -#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" if(new_user->canDecryptPrivateKey()) { responseStream << "\n"; responseStream << "\t\t\t

    Dein Privat Key konnte noch entschlüsselt werden. Es könnte also eine neue Passphrase generiert werden und dein aktueller Kontostand\n"; responseStream << "\t\t\tauf die neue Adresse transferiert werden.

    \n"; @@ -297,27 +296,27 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t"; -#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t

    Dein Privat Key konnte nicht entschlüsselt werden. Bitte wende dich an den Admin: "; -#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( adminEmail ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } responseStream << "\n"; responseStream << "\t"; -#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } else if(SHOW_PASSPHRASE == state) { responseStream << "\n"; responseStream << "\t\t

    Deine neue Passphrase, bitte schreibe sie dir auf (am besten auf einen Zettel) und hebe sie gut auf. \n"; responseStream << "\t\tDu brauchst sie wenn du dein Passwort vergessen hast oder dein Konto umziehen möchtest:

    \n"; responseStream << "\t\t
    Deine neue Passphrase:\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t"; -#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( mSession->getPassphrase()->getString() ); responseStream << "\n"; responseStream << "\t\t\t
    \n"; @@ -328,15 +327,15 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t

    \n"; responseStream << "\t\t\n"; responseStream << "\t"; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } else if(FINISH == state) { responseStream << "\n"; responseStream << "\t\t

    Neue Daten erfolgreich gespeichert, bitte logge dich nun aus. Danach kannst du dich gerne wieder einloggen und müsstest dein Guthaben wieder auf deinem Konto haben.

    \n"; responseStream << "\t\tAusloggen\n"; responseStream << "\t"; -#line 218 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } responseStream << "\n"; responseStream << "
    \n"; // begin include footer.cpsp diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 899779fef..2f3a9a802 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -3,7 +3,7 @@ #include "proto/gradido/TransactionBody.pb.h" -#include "model/User.h" +//#include "model/User.h" #include "model/Session.h" #include "lib/Profiler.h" #include "ServerConfig.h" @@ -36,7 +36,7 @@ int main(int argc, char** argv) ServerConfig::g_versionString = Poco::DateTimeFormatter::format(buildDateTime, "0.%y.%m.%d"); //ServerConfig::g_versionString = "0.20.KW13.02"; printf("Version: %s\n", ServerConfig::g_versionString.data()); - printf("User size: %d Bytes, Session size: %d Bytes\n", (int)sizeof(User), (int)sizeof(Session)); + printf("User size: %d Bytes, Session size: %d Bytes\n", (int)sizeof(controller::User), (int)sizeof(Session)); printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", (int)sizeof(model::table::User), (int)sizeof(model::table::EmailOptIn)); // load word lists diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index c7ec76f98..45f2c65ae 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -181,7 +181,7 @@ KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), crypto_sign_PUBLICKEYBYTES); if(crypto_key.isNull()) { crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); diff --git a/src/cpsp/repairDefectPassphrase.cpsp b/src/cpsp/repairDefectPassphrase.cpsp index 0e8c82e64..960466cd5 100644 --- a/src/cpsp/repairDefectPassphrase.cpsp +++ b/src/cpsp/repairDefectPassphrase.cpsp @@ -7,11 +7,10 @@ <%! #include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/EmailManager.h" -#include "../Crypto/KeyPair.h" #include "../Crypto/Passphrase.h" #include "../Crypto/KeyPairEd25519.h" #include "../lib/DataTypeConverter.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "../tasks/SigningTransaction.h" #include "../ServerConfig.h" From be4d2e87cd4cd01d667aa7851c0f9bbcb2dc94a4 Mon Sep 17 00:00:00 2001 From: dario Linux Date: Tue, 6 Oct 2020 15:44:11 +0200 Subject: [PATCH 043/195] update cmake for unix --- CMakeLists.txt | 247 ++++++++++++++++----------------- compile_pot.sh | 0 src/cpp/Crypto/KeyPairHedera.h | 1 - src/cpp/main.cpp | 1 - src/proto | 2 +- 5 files changed, 123 insertions(+), 128 deletions(-) mode change 100644 => 100755 compile_pot.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f442c87e..42b3410bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.18.2) project(Gradido_LoginServer C CXX) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin" ) @@ -16,11 +16,10 @@ include_directories( "dependencies/grpc/third_party/protobuf/src" #"dependencies/grpc/third_party/boringssl-with-bazel/src/include" "src/cpp/proto" - #"dependencies/mariadb-connector-c/build/include" - #"dependencies/mariadb-connector-c/include" - #"import/mariadb/include" ) +set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") + FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") @@ -59,51 +58,84 @@ SET(LOCAL_TEST_SRC aux_source_directory("src/cpp" LOCAL_SRCS) if(MSVC) -# src -source_group("controller" FILES ${CONTROLLER}) -source_group("proto\\gradido" FILES ${PROTO_GRADIDO}) -source_group("proto\\hedera" FILES ${PROTO_HEDERA}) -source_group("tinf" FILES ${TINF}) -source_group("Crypto" FILES ${CRYPTO}) -source_group("tasks" FILES ${TASKS}) -source_group("model\\table" FILES ${MODEL_TABLE}) -source_group("model\\email" FILES ${MODEL_EMAIL}) -source_group("model\\hedera" FILES ${MODEL_HEDERA}) -source_group("model" FILES ${MODEL}) -source_group("mysql" FILES ${MYSQL}) -source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) -source_group("lib" FILES ${LIB_SRC}) -source_group("HTTP-Interface" FILES ${HTTPInterface}) -source_group("Json-Interface" FILES ${JSONInterface}) -source_group("Test\\crypto" FILES ${TEST_CRYPTO}) -source_group("Test\\model\\table" FILES ${TEST_MODEL_TABLE}) -source_group("Test\\model" FILES ${TEST_MODEL}) -source_group("Test\\controller" FILES ${TEST_CONTROLLER}) -source_group("Test" FILES ${TEST}) + # src + source_group("controller" FILES ${CONTROLLER}) + source_group("proto\\gradido" FILES ${PROTO_GRADIDO}) + source_group("proto\\hedera" FILES ${PROTO_HEDERA}) + source_group("tinf" FILES ${TINF}) + source_group("Crypto" FILES ${CRYPTO}) + source_group("tasks" FILES ${TASKS}) + source_group("model\\table" FILES ${MODEL_TABLE}) + source_group("model\\email" FILES ${MODEL_EMAIL}) + source_group("model\\hedera" FILES ${MODEL_HEDERA}) + source_group("model" FILES ${MODEL}) + source_group("mysql" FILES ${MYSQL}) + source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) + source_group("lib" FILES ${LIB_SRC}) + source_group("HTTP-Interface" FILES ${HTTPInterface}) + source_group("Json-Interface" FILES ${JSONInterface}) + source_group("Test\\crypto" FILES ${TEST_CRYPTO}) + source_group("Test\\model\\table" FILES ${TEST_MODEL_TABLE}) + source_group("Test\\model" FILES ${TEST_MODEL}) + source_group("Test\\controller" FILES ${TEST_CONTROLLER}) + source_group("Test" FILES ${TEST}) endif(MSVC) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() -#add_subdirectory("dependencies/curl") -#add_subdirectory("dependencies/mariadb-connector-c") - add_executable(Gradido_LoginServer ${LOCAL_SRCS}) -#SUBDIRS("src/test") + + +set(DEP_PATH "dependencies") +set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") +set(GRPC_PATH "${DEP_PATH}/grpc/build") +set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types") +set(GRPC_CARES_PATH "${GRPC_PATH}/third_party/cares/cares/lib") +set(GRPC_BORING_SSL_PATH "${GRPC_PATH}/third_party/boringssl-with-bazel") +set(GRPC_RE2_PATH "${GRPC_PATH}/third_party/re2") +set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf") if(WIN32) -find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-connector-c/build/libmariadb/Release" REQUIRED) -#find_library(MYSQL_LIBRARIES_DEBUG mariadbclient.lib PATHS "import/mariadb/lib/debug") -find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) -set(GRPC_PATH "dependencies/grpc/_build/Debug") -set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/Debug") -set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") -set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") -set(GRPC_RE2_PATH "dependencies/grpc/_build/third_party/re2/Debug") -set(GRPC_PROTOBUF_DEBUG_PATH "dependencies/grpc/_build/third_party/protobuf/Debug") + find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) + find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "${MARIADB_CONNECTOR_PATH}/Debug" REQUIRED) + + set(GRPC_PATH "${GRPC_PATH}/Debug") + set(GRPC_ABSL_PATH "${GRPC_ABSL_PATH}/Debug") + set(GRPC_CARES_PATH "${GRPC_CARES_PATH}/Debug") + set(GRPC_BORING_SSL_PATH "${GRPC_CGRPC_BORING_SSL_PATHARES_PATH}/Debug") + set(GRPC_RE2_PATH "${GRPC_RE2_PATH}/Debug") + set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}/Debug") + + find_library(PROTOBUF_LIB_DEBUG libprotobufd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) + find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) + find_library(PROTOBUF_LIBC_DEBUG libprotocd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) + + set(PROTOBUF_DEBUG_LIBS + ${PROTOBUF_LIB_DEBUG} + ${PROTOBUF_LIB_LITE_DEBUG} + ${PROTOBUF_LIBC_DEBUG} + ) + + list(REMOVE_ITEM CONAN_LIBS "libeay32.lib") + list(REMOVE_ITEM CONAN_LIBS "ssleay32.lib") + + +else (WIN32) +# message(STATUS ${MARIADB_CONNECTOR_PATH}) + find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) + set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") + + list(REMOVE_ITEM CONAN_LIBS "ssl") + list(REMOVE_ITEM CONAN_LIBS "crypto") + + +endif(WIN32) + +# grpc libs find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) @@ -113,15 +145,18 @@ find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) +# grpc third party libs find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_RE2 re2 ${GRPC_RE2_PATH} REQUIRED) -find_library(PROTOBUF_LIB_DEBUG libprotobufd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) -find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) -find_library(PROTOBUF_LIBC_DEBUG libprotocd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_RE2 re2 PATHS ${GRPC_RE2_PATH} REQUIRED) + +find_library(PROTOBUF_LIB libprotobuf.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) +find_library(PROTOBUF_LIB_LITE libprotobuf-lite.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) +find_library(PROTOBUF_LIBC libprotoc.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) + +find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access PATHS ${GRPC_ABSL_PATH} REQUIRED) -find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} @@ -131,74 +166,49 @@ set(GRPC_LIBS ${GRPC_BORING_SSL_SSL} ${GRPC_RE2} ) -set(PROTOBUF_DEBUG_LIBS - ${PROTOBUF_LIB_DEBUG} - ${PROTOBUF_LIB_LITE_DEBUG} - ${PROTOBUF_LIBC_DEBUG} + +set(PROTOBUF_LIBS + ${PROTOBUF_LIB} + ${PROTOBUF_LIB_LITE} + ${PROTOBUF_LIBC} ) -set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") +if(WIN32) -#set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") -#find_library(POCO_DEBUG_FOUNDATION PocoFoundationd PocoFoundation PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_DATA PocoDatad PocoData PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_NET PocoNetd PocoNet PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_NET_SSL PocoNetSSLd PocoNetSSL PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_UTIL PocoUtild PocoUtil PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_CRYPTO PocoCryptod PocoCrypto PATHS ${POCO_DEBUG_PATH} REQUIRED) - -#set(POCO_DEBUG_LIBS ${POCO_DEBUG_FOUNDATION} ${POCO_DEBUG_UTIL} ${POCO_DEBUG_DATA} ${POCO_DEBUG_NET} ${POCO_DEBUG_NET_SSL} ${POCO_DEBUG_CRYPTO}) -#include_directories( -# "I:/FremdCode/C++/poco/Foundation/include" -# "I:/FremdCode/C++/poco/Data/include" -# "I:/FremdCode/C++/poco/Net/include" - #"I:/FremdCode/C++/poco/NetSSL_Win/include" -# "I:/FremdCode/C++/poco/NetSSL_OpenSSL/include" -# "I:/FremdCode/C++/poco/Crypto/include" -# "I:/FremdCode/C++/poco/Util/include" -# "I:/FremdCode/C++/ssl/include" -#) - -set(CMAKE_CXX_FLAGS "/MP /EHsc") -#set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") -#set(CMAKE_CXX_FLAGS_RELEASE "-O3") + set(CMAKE_CXX_FLAGS "/MP /EHsc") + #set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") + #set(CMAKE_CXX_FLAGS_RELEASE "-O3") else(WIN32) -set(GRPC_BORING_SSL_PATH "dependencies/grpc/build/third_party/boringssl-with-bazel") -find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) -set(GRPC_LIBS - #${GRPC_BORING_SSL_CRYPTO} - #${GRPC_BORING_SSL_SSL} -) -#find_package(OpenSSL REQUIRED) -find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) -set(gRPC_SSL_PROVIDER "module") -find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) -find_package(Threads REQUIRED) -set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) -#find_package(Poco REQUIRED) -#find_package(libsodium REQUIRED) -#find_package(gtest REQUIRED) -find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) -# set vars for mariadb cmake files -set(INSTALL_BINDIR "bin") -set(INSTALL_PLUGINDIR "bin") -OPTION(WITH_SSL "" OFF) -add_subdirectory("dependencies/mariadb-connector-c") + #find_package(OpenSSL REQUIRED) + #find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) + #set(gRPC_SSL_PROVIDER "module") + #find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) + find_package(Threads REQUIRED) + set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) + + #find_package(Poco REQUIRED) + #find_package(libsodium REQUIRED) + #find_package(gtest REQUIRED) + #find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) + # set vars for mariadb cmake files + set(INSTALL_BINDIR "bin") + set(INSTALL_PLUGINDIR "bin") +# OPTION(WITH_SSL "" OFF) +# add_subdirectory("dependencies/mariadb-connector-c") -include_directories( - "dependencies/mariadb-connector-c/include" - "build/dependencies/mariadb-connector-c/include" - #${OpenSSL_INCLUDE_DIR} - #${Poco_INCLUDE_DIR} - #${libsodium_INCLUDE_DIR} - #${gtest_INCLUDE_DIR} -) + include_directories( + # "dependencies/mariadb-connector-c/include" +# "build/dependencies/mariadb-connector-c/include" + #${OpenSSL_INCLUDE_DIR} + #${Poco_INCLUDE_DIR} + #${libsodium_INCLUDE_DIR} + #${gtest_INCLUDE_DIR} + ) @@ -207,30 +217,17 @@ endif(WIN32) add_subdirectory("dependencies/grpc/third_party/abseil-cpp") -#target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings)# ${CONAN_LIBS} ${IROHA_ED25519}) -message(STATUS "Conan libs: ") -list(REMOVE_ITEM CONAN_LIBS "ssl") -list(REMOVE_ITEM CONAN_LIBS "crypto") -foreach(i ${CONAN_LIBS}) - -message(STATUS ${i}) - -endforeach(i) - - target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS}) if(WIN32) -TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) -else(WIN32) -target_link_libraries(Gradido_LoginServer gRPC::grpc++) -target_link_libraries(Gradido_LoginServer ${CONAN_LIBS}) -target_link_libraries(Gradido_LoginServer libmariadb )# ${GRPC_LIBS} protoc protobuf pthread) -#target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) - - + TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) +else(WIN32) # unix +# target_link_libraries(Gradido_LoginServer gRPC::grpc++) +# target_link_libraries(Gradido_LoginServer ) + target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${GRPC_LIBS} ${PROTOBUF_LIBS} )# ${GRPC_LIBS} protoc protobuf pthread) + #target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) endif(WIN32) @@ -255,7 +252,7 @@ enable_testing() add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") -target_link_libraries(Gradido_LoginServer_Test absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) +target_link_libraries(Gradido_LoginServer_Test absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) diff --git a/compile_pot.sh b/compile_pot.sh old mode 100644 new mode 100755 diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 769f29af6..f342164d6 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -14,7 +14,6 @@ #include "sodium.h" #include "SecretKeyCryptography.h" -#include "iroha-ed25519/include/ed25519/ed25519.h" #include "../lib/DataTypeConverter.h" class KeyPairHedera : public IKeyPair diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 899779fef..8d3858923 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -3,7 +3,6 @@ #include "proto/gradido/TransactionBody.pb.h" -#include "model/User.h" #include "model/Session.h" #include "lib/Profiler.h" #include "ServerConfig.h" diff --git a/src/proto b/src/proto index 81a461566..72e8fe7b7 160000 --- a/src/proto +++ b/src/proto @@ -1 +1 @@ -Subproject commit 81a461566e46d71533dc3e284fa075d7d68fd020 +Subproject commit 72e8fe7b73a1aaf2d057d2fef59ade9268830008 From d170cf5e270d80e249933f13710ab475bcfea31c Mon Sep 17 00:00:00 2001 From: dario Linux Date: Wed, 7 Oct 2020 12:39:55 +0200 Subject: [PATCH 044/195] more experiments with cmake --- CMakeLists.txt | 54 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1546672f8..7b1c3e7d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,8 +129,9 @@ else (WIN32) find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") -# list(REMOVE_ITEM CONAN_LIBS "ssl") -# list(REMOVE_ITEM CONAN_LIBS "crypto") + list(REMOVE_ITEM CONAN_LIBS "ssl") + list(REMOVE_ITEM CONAN_LIBS "crypto") + list(REMOVE_ITEM CONAN_LIBS "dl") endif(WIN32) @@ -142,6 +143,7 @@ find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_LIB grpc PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_LIB_UNSECURE grpc_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ERROR_DETAILS grpc++_error_details PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) @@ -149,8 +151,8 @@ find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) # grpc third party libs find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +#find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +#find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_RE2 re2 PATHS ${GRPC_RE2_PATH} REQUIRED) find_library(PROTOBUF_LIB libprotobuf.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) @@ -159,13 +161,35 @@ find_library(PROTOBUF_LIBC libprotoc.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access PATHS ${GRPC_ABSL_PATH} REQUIRED) +# load same ssl version like used from poco +find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) +find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) +#find_library(CONAN_OPENSSL_DL dl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) +#find_library(CONAN_OPENSSL_PTHREAD pthread PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) + +set(CONAN_OPENSSL_CUSTOM_LIBS + ${CONAN_OPENSSL_SSL} + ${CONAN_OPENSSL_CRYPTO} + #${CONAN_OPENSSL_DL} +# ${CONAN_OPENSSL_PTHREAD} + ) +#foreach(i ${CONAN_LIBS_OPENSSL}) +# find_library(_LIB_${i} ${i} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) + #set(CONAN_POCO_OPENSSL_LIBS ${CONAN_POCO_OPENSSL_LIBS} ${_LIB_${i}}) +#endforeach(i) + +#${CONAN_LIB_DIRS_OPENSSL} +#${CONAN_LIBS_OPENSSL} +#find_library(CONAN_POCO_OPENSSL_LIBS NAMES ${CONAN_LIBS_OPENSSL} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) + set(GRPC_LIBS - ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} + ${GRPC_PLUSPLUS} + ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} ${GRPC_CARES} - ${GRPC_BORING_SSL_CRYPTO} - ${GRPC_BORING_SSL_SSL} +# ${GRPC_BORING_SSL_CRYPTO} +# ${GRPC_BORING_SSL_SSL} ${GRPC_RE2} ) @@ -229,10 +253,24 @@ if(WIN32) else(WIN32) # unix # target_link_libraries(Gradido_LoginServer gRPC::grpc++) # target_link_libraries(Gradido_LoginServer ) - target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${GRPC_LIBS} ${PROTOBUF_LIBS} ${CMAKE_DL_LIBS} )# ${GRPC_LIBS} protoc protobuf pthread) + target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS})# ${GRPC_LIBS} protoc protobuf pthread) #target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) endif(WIN32) +message(STATUS "link libraries:" ) +get_target_property(OUT Gradido_LoginServer LINK_LIBRARIES) +foreach(i ${OUT}) +message(STATUS ${i}) +endforeach(i) +message(STATUS "grpc libs: ") +foreach(i ${GRPC_LIBS}) +message(STATUS ${i}) +endforeach(i) +message(STATUS "boring ssl:") +message(STATUS ${GRPC_BORING_SSL_SSL}) +message(STATUS ${GRPC_BORING_SSL_CRYPTO}) +message(STATUS "Conan OpenSSL") +message(STATUS ${CONAN_POCO_OPENSSL_LIBS}) # install if(UNIX) From 09f2ae27de59ba78b29e95bed2eae103e21e5824 Mon Sep 17 00:00:00 2001 From: dario Linux Date: Thu, 8 Oct 2020 08:23:09 +0200 Subject: [PATCH 045/195] build working under linux :) --- CMakeLists.txt | 121 +++------------------ FindOpenSSL.cmake | 109 +++++++++++++++++++ conanfile.txt | 1 - src/cpp/test/crypto/TestKeyPairEd25519.cpp | 10 +- src/cpp/test/crypto/TestPassphrase.cpp | 9 +- 5 files changed, 134 insertions(+), 116 deletions(-) create mode 100644 FindOpenSSL.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b1c3e7d4..1648b666e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,14 +14,12 @@ include_directories( "dependencies/spirit-po/include" "dependencies/grpc/include" "dependencies/grpc/third_party/protobuf/src" - #"dependencies/grpc/third_party/boringssl-with-bazel/src/include" "src/cpp/proto" ) set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") - FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h") FILE(GLOB HTTPInterface "src/cpp/HTTPInterface/*.h" "src/cpp/HTTPInterface/*.cpp") @@ -91,6 +89,7 @@ add_executable(Gradido_LoginServer ${LOCAL_SRCS}) set(DEP_PATH "dependencies") set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") + set(GRPC_PATH "${DEP_PATH}/grpc/build") set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types") set(GRPC_CARES_PATH "${GRPC_PATH}/third_party/cares/cares/lib") @@ -98,6 +97,8 @@ set(GRPC_BORING_SSL_PATH "${GRPC_PATH}/third_party/boringssl-with-bazel") set(GRPC_RE2_PATH "${GRPC_PATH}/third_party/re2") set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf") + + if(WIN32) find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) @@ -125,7 +126,7 @@ if(WIN32) else (WIN32) -# message(STATUS ${MARIADB_CONNECTOR_PATH}) + find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") @@ -136,141 +137,51 @@ else (WIN32) endif(WIN32) -message(STATUS ${MARIADB_CONNECTOR_PATH}) - -# grpc libs -find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_LIB grpc PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_LIB_UNSECURE grpc_unsecure PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_ERROR_DETAILS grpc++_error_details PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) -# grpc third party libs -find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) -#find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) -#find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_RE2 re2 PATHS ${GRPC_RE2_PATH} REQUIRED) - -find_library(PROTOBUF_LIB libprotobuf.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) -find_library(PROTOBUF_LIB_LITE libprotobuf-lite.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) -find_library(PROTOBUF_LIBC libprotoc.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) - -find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access PATHS ${GRPC_ABSL_PATH} REQUIRED) - # load same ssl version like used from poco +find_package(OpenSSL PATHS . NO_DEFAULT_PATH) + find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) -#find_library(CONAN_OPENSSL_DL dl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) -#find_library(CONAN_OPENSSL_PTHREAD pthread PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(CONAN_OPENSSL_CUSTOM_LIBS ${CONAN_OPENSSL_SSL} ${CONAN_OPENSSL_CRYPTO} - #${CONAN_OPENSSL_DL} -# ${CONAN_OPENSSL_PTHREAD} - ) -#foreach(i ${CONAN_LIBS_OPENSSL}) -# find_library(_LIB_${i} ${i} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) - #set(CONAN_POCO_OPENSSL_LIBS ${CONAN_POCO_OPENSSL_LIBS} ${_LIB_${i}}) -#endforeach(i) - -#${CONAN_LIB_DIRS_OPENSSL} -#${CONAN_LIBS_OPENSSL} -#find_library(CONAN_POCO_OPENSSL_LIBS NAMES ${CONAN_LIBS_OPENSSL} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) - -set(GRPC_LIBS - ${GRPC_PLUSPLUS} - ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} - ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} - ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} - ${GRPC_CARES} -# ${GRPC_BORING_SSL_CRYPTO} -# ${GRPC_BORING_SSL_SSL} - ${GRPC_RE2} ) -set(PROTOBUF_LIBS - ${PROTOBUF_LIB} - ${PROTOBUF_LIB_LITE} - ${PROTOBUF_LIBC} -) +set(BUILD_TESTING OFF) +set(gRPC_SSL_PROVIDER "package") +add_subdirectory("dependencies/grpc/") +message(STATUS "Using gRPC via add_subdirectory.") if(WIN32) - set(CMAKE_CXX_FLAGS "/MP /EHsc") #set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") #set(CMAKE_CXX_FLAGS_RELEASE "-O3") else(WIN32) - #find_package(OpenSSL REQUIRED) - #find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) - #set(gRPC_SSL_PROVIDER "module") - #find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) -# find_package(Threads REQUIRED) -# set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) - - #find_package(Poco REQUIRED) - #find_package(libsodium REQUIRED) - #find_package(gtest REQUIRED) - #find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) - # set vars for mariadb cmake files set(INSTALL_BINDIR "bin") set(INSTALL_PLUGINDIR "bin") -# OPTION(WITH_SSL "" OFF) -# add_subdirectory("dependencies/mariadb-connector-c") - include_directories( - # "dependencies/mariadb-connector-c/include" -# "build/dependencies/mariadb-connector-c/include" ${CONAN_INCLUDE_DIRS_OPENSSL} - #${OpenSSL_INCLUDE_DIR} - #${Poco_INCLUDE_DIR} - #${libsodium_INCLUDE_DIR} - #${gtest_INCLUDE_DIR} ) - endif(WIN32) -add_subdirectory("dependencies/grpc/third_party/abseil-cpp") - - -target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS}) +set(GRPC_LIBS libprotobuf grpc++_reflection grpc++) +target_link_libraries(Gradido_LoginServer ${CONAN_LIBS}) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) # unix -# target_link_libraries(Gradido_LoginServer gRPC::grpc++) -# target_link_libraries(Gradido_LoginServer ) - target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS})# ${GRPC_LIBS} protoc protobuf pthread) - #target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) - + target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) endif(WIN32) -message(STATUS "link libraries:" ) -get_target_property(OUT Gradido_LoginServer LINK_LIBRARIES) -foreach(i ${OUT}) -message(STATUS ${i}) -endforeach(i) -message(STATUS "grpc libs: ") -foreach(i ${GRPC_LIBS}) -message(STATUS ${i}) -endforeach(i) -message(STATUS "boring ssl:") -message(STATUS ${GRPC_BORING_SSL_SSL}) -message(STATUS ${GRPC_BORING_SSL_CRYPTO}) -message(STATUS "Conan OpenSSL") -message(STATUS ${CONAN_POCO_OPENSSL_LIBS}) # install if(UNIX) @@ -288,19 +199,19 @@ enable_testing() # ---------------------- Test ----------------------------------------- #project(Gradido_LoginServer_Test C CXX) #_TEST_BUILD - +#find_package(gtest) add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") -target_link_libraries(Gradido_LoginServer_Test absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ) +target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) - target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf pthread) + target_link_libraries(Gradido_LoginServer_Test ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) endif(WIN32) add_test(NAME main COMMAND Gradido_LoginServer_Test) diff --git a/FindOpenSSL.cmake b/FindOpenSSL.cmake new file mode 100644 index 000000000..4a4fec7df --- /dev/null +++ b/FindOpenSSL.cmake @@ -0,0 +1,109 @@ + + +function(conan_message MESSAGE_OUTPUT) + if(NOT CONAN_CMAKE_SILENT_OUTPUT) + message(${ARGV${0}}) + endif() +endfunction() + + + + +include(FindPackageHandleStandardArgs) + +conan_message(STATUS "Conan: Using autogenerated FindOpenSSL.cmake") +# Global approach +set(OpenSSL_FOUND 1) +set(OpenSSL_VERSION "1.0.2o") + +find_package_handle_standard_args(OpenSSL REQUIRED_VARS + OpenSSL_VERSION VERSION_VAR OpenSSL_VERSION) +mark_as_advanced(OpenSSL_FOUND OpenSSL_VERSION) + + +set(OpenSSL_INCLUDE_DIRS "${CONAN_INCLUDE_DIRS_OPENSSL}") +set(OpenSSL_INCLUDE_DIR "${CONAN_INCLUDE_DIRS_OPENSSL}") +set(OpenSSL_INCLUDES "${CONAN_INCLUDE_DIRS_OPENSSL}") +set(OpenSSL_RES_DIRS "${CONAN_RES_DIRS_OPENSSL}") +set(OpenSSL_DEFINITIONS ) +set(OpenSSL_LINKER_FLAGS_LIST + "$<$,SHARED_LIBRARY>:>" + "$<$,MODULE_LIBRARY>:>" + "$<$,EXECUTABLE>:>" +) +set(OpenSSL_COMPILE_DEFINITIONS ) +set(OpenSSL_COMPILE_OPTIONS_LIST "" "") +set(OpenSSL_COMPILE_OPTIONS_C "") +set(OpenSSL_COMPILE_OPTIONS_CXX "") +set(OpenSSL_LIBRARIES_TARGETS "") # Will be filled later, if CMake 3 +set(OpenSSL_LIBRARIES "") # Will be filled later +set(OpenSSL_LIBS "") # Same as OpenSSL_LIBRARIES +set(OpenSSL_FRAMEWORKS_FOUND "") # Will be filled later +set(OpenSSL_BUILD_MODULES_PATHS ) + + +mark_as_advanced(OpenSSL_INCLUDE_DIRS + OpenSSL_INCLUDE_DIR + OpenSSL_INCLUDES + OpenSSL_DEFINITIONS + OpenSSL_LINKER_FLAGS_LIST + OpenSSL_COMPILE_DEFINITIONS + OpenSSL_COMPILE_OPTIONS_LIST + OpenSSL_LIBRARIES + OpenSSL_LIBS + OpenSSL_LIBRARIES_TARGETS) + +# Find the real .lib/.a and add them to OpenSSL_LIBS and OpenSSL_LIBRARY_LIST +set(OpenSSL_LIBRARY_LIST ssl crypto dl pthread) +set(OpenSSL_LIB_DIRS "${CONAN_LIB_DIRS_OPENSSL}") + +# Gather all the libraries that should be linked to the targets (do not touch existing variables): +set(_OpenSSL_DEPENDENCIES "zlib::zlib") + +conan_package_library_targets("${OpenSSL_LIBRARY_LIST}" # libraries + "${OpenSSL_LIB_DIRS}" # package_libdir + "${_OpenSSL_DEPENDENCIES}" # deps + OpenSSL_LIBRARIES # out_libraries + OpenSSL_LIBRARIES_TARGETS # out_libraries_targets + "" # build_type + "OpenSSL") # package_name + +set(OpenSSL_LIBS ${OpenSSL_LIBRARIES}) + +# We need to add our requirements too +set(OpenSSL_LIBRARIES_TARGETS "${OpenSSL_LIBRARIES_TARGETS};zlib::zlib") +set(OpenSSL_LIBRARIES "${OpenSSL_LIBRARIES};zlib::zlib") + +set(CMAKE_MODULE_PATH "/home/dario/.conan/data/OpenSSL/1.0.2o/conan/stable/package/b781af3f476d0aa5070a0a35b544db7a3c193cc8/" ${CMAKE_MODULE_PATH}) +set(CMAKE_PREFIX_PATH "/home/dario/.conan/data/OpenSSL/1.0.2o/conan/stable/package/b781af3f476d0aa5070a0a35b544db7a3c193cc8/" ${CMAKE_PREFIX_PATH}) + +foreach(_BUILD_MODULE_PATH ${OpenSSL_BUILD_MODULES_PATHS}) + include(${_BUILD_MODULE_PATH}) +endforeach() + +if(NOT ${CMAKE_VERSION} VERSION_LESS "3.0") + # Target approach + if(NOT TARGET OpenSSL::OpenSSL) + add_library(OpenSSL::OpenSSL INTERFACE IMPORTED) + if(OpenSSL_INCLUDE_DIRS) + set_target_properties(OpenSSL::OpenSSL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OpenSSL_INCLUDE_DIRS}") + endif() + set_property(TARGET OpenSSL::OpenSSL PROPERTY INTERFACE_LINK_LIBRARIES + "${OpenSSL_LIBRARIES_TARGETS};${OpenSSL_LINKER_FLAGS_LIST}") + set_property(TARGET OpenSSL::OpenSSL PROPERTY INTERFACE_COMPILE_DEFINITIONS + ${OpenSSL_COMPILE_DEFINITIONS}) + set_property(TARGET OpenSSL::OpenSSL PROPERTY INTERFACE_COMPILE_OPTIONS + "${OpenSSL_COMPILE_OPTIONS_LIST}") + + # Library dependencies + include(CMakeFindDependencyMacro) + + if(NOT zlib_FOUND) + find_dependency(zlib REQUIRED) + else() + message(STATUS "Dependency zlib already found") + endif() + + endif() +endif() diff --git a/conanfile.txt b/conanfile.txt index a6c09d9fa..703260a39 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -6,4 +6,3 @@ gtest/1.8.1@bincrafters/stable [generators] cmake - diff --git a/src/cpp/test/crypto/TestKeyPairEd25519.cpp b/src/cpp/test/crypto/TestKeyPairEd25519.cpp index 314fb9cdc..51f714776 100644 --- a/src/cpp/test/crypto/TestKeyPairEd25519.cpp +++ b/src/cpp/test/crypto/TestKeyPairEd25519.cpp @@ -1,6 +1,6 @@ #include "TestPassphrase.h" -#include "../../Crypto/KeyPair.h" + #include "../../Crypto/KeyPairEd25519.h" #include "../../Crypto/Passphrase.h" #include "../../lib/DataTypeConverter.h" @@ -14,12 +14,12 @@ TEST_F(PassphraseTest, TestEd25519KeyPair) { auto word_indices = tr->getWordIndices(); auto key_pair_ed25519 = KeyPairEd25519::create(tr); - KeyPair key_pair; + //KeyPair key_pair; - key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); + //key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); - EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); - EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), key_pair.getPubkeyHex()); + //EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); + //EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), key_pair.getPubkeyHex()); //auto key_pair_old delete key_pair_ed25519; diff --git a/src/cpp/test/crypto/TestPassphrase.cpp b/src/cpp/test/crypto/TestPassphrase.cpp index 128a461f6..010353e17 100644 --- a/src/cpp/test/crypto/TestPassphrase.cpp +++ b/src/cpp/test/crypto/TestPassphrase.cpp @@ -10,7 +10,6 @@ #include "../../lib/DataTypeConverter.h" #include "../../Crypto/KeyPairEd25519.h" -#include "../../Crypto/KeyPair.h" @@ -170,10 +169,10 @@ TEST_F(PassphraseTest, createAndTransform) { EXPECT_EQ(word_indices[i], test_data_set.wordIndices[i]); } auto key_pair_ed25519 = KeyPairEd25519::create(tr); - KeyPair key_pair; - key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); - //EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), test_data_set.pubkeyHex); - EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); + //KeyPair key_pair; + //key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); + EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), test_data_set.pubkeyHex); + //EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); //auto key_pair_old delete key_pair_ed25519; From 6a53b19a4230f6ed731eca40f4583e9f7fd54bf8 Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 8 Oct 2020 11:40:03 +0200 Subject: [PATCH 046/195] adding PendingTask model and controller --- src/cpp/controller/PendingTask.cpp | 36 +++++++++++ src/cpp/controller/PendingTask.h | 37 ++++++++++++ src/cpp/model/table/PendingTask.cpp | 94 +++++++++++++++++++++++++++++ src/cpp/model/table/PendingTask.h | 61 +++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 src/cpp/controller/PendingTask.cpp create mode 100644 src/cpp/controller/PendingTask.h create mode 100644 src/cpp/model/table/PendingTask.cpp create mode 100644 src/cpp/model/table/PendingTask.h diff --git a/src/cpp/controller/PendingTask.cpp b/src/cpp/controller/PendingTask.cpp new file mode 100644 index 000000000..417813762 --- /dev/null +++ b/src/cpp/controller/PendingTask.cpp @@ -0,0 +1,36 @@ +#include "PendingTask.h" + +namespace controller { + + PendingTask::PendingTask(model::table::PendingTask* dbModel) + { + mDBModel = dbModel; + } + + PendingTask::~PendingTask() + { + + } + + Poco::AutoPtr PendingTask::create(int userId, std::string serializedProtoRequest, model::table::TaskType type) + { + auto db = new model::table::PendingTask(userId, serializedProtoRequest, type); + auto pending_task = new PendingTask(db); + return Poco::AutoPtr(pending_task); + } + + std::vector> PendingTask::load(int userId) + { + auto db = new model::table::PendingTask(); + auto pending_task_list = db->loadFromDB("user_id", userId, 3); + std::vector> resultVector; + resultVector.reserve(pending_task_list.size()); + for (auto it = pending_task_list.begin(); it != pending_task_list.end(); it++) { + resultVector.push_back(new PendingTask(new model::table::PendingTask(*it))); + } + return resultVector; + + + } + +} \ No newline at end of file diff --git a/src/cpp/controller/PendingTask.h b/src/cpp/controller/PendingTask.h new file mode 100644 index 000000000..821f4a141 --- /dev/null +++ b/src/cpp/controller/PendingTask.h @@ -0,0 +1,37 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_PENDING_TASK_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_PENDING_TASK_INCLUDE + +#include "../model/table/PendingTask.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + + + typedef Poco::Tuple NodeServerFullTuple; + + class PendingTask : public TableControllerBase + { + public: + + ~PendingTask(); + + static Poco::AutoPtr create(int userId, std::string serializedProtoRequest, model::table::TaskType type); + + static std::vector> load(int userId); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + PendingTask(model::table::PendingTask* dbModel); + + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_PENDING_TASK_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/PendingTask.cpp b/src/cpp/model/table/PendingTask.cpp new file mode 100644 index 000000000..6248333f8 --- /dev/null +++ b/src/cpp/model/table/PendingTask.cpp @@ -0,0 +1,94 @@ +#include "PendingTask.h" + +//#include + +using namespace Poco::Data::Keywords; + +namespace model +{ + namespace table + { + PendingTask::PendingTask() + : mUserId(0), mTaskTypeId(TASK_TYPE_NONE) + { + + } + PendingTask::PendingTask(int userId, std::string serializedProtoRequest, TaskType type) + : mUserId(userId), mRequest((const unsigned char*)serializedProtoRequest.data(), serializedProtoRequest.size()), + mTaskTypeId(TASK_TYPE_NONE) + { + + } + PendingTask::PendingTask(const PendingTaskTuple& tuple) + : ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mRequest(tuple.get<2>()), mCreated(tuple.get<3>()), mFinished(tuple.get<4>()), + mResultJsonString(tuple.get<5>()), mTaskTypeId(tuple.get<6>()) + { + + } + PendingTask::~PendingTask() + { + + } + + + + std::string PendingTask::toString() + { + std::stringstream ss; + std::shared_lock _lock(mSharedMutex); + return ss.str(); + } + + + const char* PendingTask::typeToString(TaskType type) + { + switch (type) { + case TASK_TYPE_GROUP_CREATE: return "group create"; + case TASK_TYPE_GROUP_ADD_MEMBER: return "group add member"; + case TASK_TYPE_CREATION: return "creation"; + case TASK_TYPE_TRANSFER: return "transfer"; + case TASK_TYPE_HEDERA_TOPIC_CREATE: return "hedera topic create"; + case TASK_TYPE_HEDERA_TOPIC_MESSAGE: return "hedera topic send message"; + case TASK_TYPE_HEDERA_ACCOUNT_CREATE: return "hedera account create"; + default: return ""; + } + return ""; + } + + Poco::Data::Statement PendingTask::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, user_id, request, created, finished, result_json, task_type_id FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mUserId), into(mRequest), into(mCreated), into(mFinished), into(mResultJsonString), into(mTaskTypeId); + + return select; + } + + Poco::Data::Statement PendingTask::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " WHERE user_id = ? " + << " AND created = ? " + << " AND task_type_id = ? " + , into(mID), use(mUserId), use(mCreated), use(mTaskTypeId); + unlock(); + return select; + } + + + Poco::Data::Statement PendingTask::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (user_id, request, created, task_type_id) VALUES(?,?,?,?)" + , use(mUserId), use(mRequest), use(mCreated), use(mTaskTypeId); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/PendingTask.h b/src/cpp/model/table/PendingTask.h new file mode 100644 index 000000000..bab94448c --- /dev/null +++ b/src/cpp/model/table/PendingTask.h @@ -0,0 +1,61 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_PENDING_TASKS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_PENDING_TASKS_INCLUDE + +#include "ModelBase.h" +#include "Poco/Types.h" + +#include + +namespace model { + namespace table { + + enum TaskType { + TASK_TYPE_NONE = 0, + TASK_TYPE_GROUP_CREATE = 1, + TASK_TYPE_GROUP_ADD_MEMBER = 2, + TASK_TYPE_CREATION = 10, + TASK_TYPE_TRANSFER = 11, + TASK_TYPE_HEDERA_TOPIC_CREATE = 20, + TASK_TYPE_HEDERA_TOPIC_MESSAGE = 21, + TASK_TYPE_HEDERA_ACCOUNT_CREATE = 25, + + }; + + typedef Poco::Tuple PendingTaskTuple; + + class PendingTask : public ModelBase + { + public: + PendingTask(); + PendingTask(int userId, std::string serializedProtoRequest, TaskType type); + PendingTask(const PendingTaskTuple& tuple); + + ~PendingTask(); + + // generic db operations + const char* getTableName() const { return "pending_tasks"; } + std::string toString(); + + + static const char* typeToString(TaskType type); + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + int mUserId; + Poco::Data::BLOB mRequest; + Poco::DateTime mCreated; + Poco::DateTime mFinished; + std::string mResultJsonString; + int mTaskTypeId; + + std::shared_mutex mSharedMutex; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_PENDING_TASKS_INCLUDE \ No newline at end of file From a4ab74b5c6b156337ad11ee98df7ef07e14ce36b Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Thu, 8 Oct 2020 11:51:23 +0200 Subject: [PATCH 047/195] cmake update for windows --- CMakeLists.txt | 20 +++++++------------- README | 16 +++++++--------- windows_parse_proto.sh | 8 ++++---- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1648b666e..aaea26b43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,8 +101,11 @@ set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf") if(WIN32) - find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) + find_library(MYSQL_LIBRARIES mariadbclient PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "${MARIADB_CONNECTOR_PATH}/Debug" REQUIRED) + + find_library(CONAN_OPENSSL_SSL ssleay32 PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) + find_library(CONAN_OPENSSL_CRYPTO libeay32 PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(GRPC_PATH "${GRPC_PATH}/Debug") set(GRPC_ABSL_PATH "${GRPC_ABSL_PATH}/Debug") @@ -111,15 +114,6 @@ if(WIN32) set(GRPC_RE2_PATH "${GRPC_RE2_PATH}/Debug") set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}/Debug") - find_library(PROTOBUF_LIB_DEBUG libprotobufd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) - find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) - find_library(PROTOBUF_LIBC_DEBUG libprotocd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) - - set(PROTOBUF_DEBUG_LIBS - ${PROTOBUF_LIB_DEBUG} - ${PROTOBUF_LIB_LITE_DEBUG} - ${PROTOBUF_LIBC_DEBUG} - ) list(REMOVE_ITEM CONAN_LIBS "libeay32.lib") list(REMOVE_ITEM CONAN_LIBS "ssleay32.lib") @@ -128,6 +122,8 @@ if(WIN32) else (WIN32) find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) + find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) + find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") list(REMOVE_ITEM CONAN_LIBS "ssl") @@ -138,10 +134,8 @@ else (WIN32) endif(WIN32) # load same ssl version like used from poco -find_package(OpenSSL PATHS . NO_DEFAULT_PATH) +#find_package(OpenSSL PATHS . NO_DEFAULT_PATH) -find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) -find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(CONAN_OPENSSL_CUSTOM_LIBS ${CONAN_OPENSSL_SSL} diff --git a/README b/README index c6419d014..85f15134c 100644 --- a/README +++ b/README @@ -9,15 +9,6 @@ cmake -DWITH_SSL=OFF .. cd ../../../ -cd dependencies/grpc -mkdir build -cd build -cmake .. -make -# under windows build at least release for protoc.exe and grpc c++ plugin -cd ../../../ -./unix_parse_proto.sh - # get more dependencies with conan (need conan from https://conan.io/) mkdir build && cd build # // not used anymore @@ -29,3 +20,10 @@ conan install .. # build Makefile with cmake cmake .. +make grpc +# under windows build at least release for protoc.exe and grpc c++ plugin +cd ../ +./unix_parse_proto.sh +cd build +make + diff --git a/windows_parse_proto.sh b/windows_parse_proto.sh index 4c5d56d47..90497e6b8 100644 --- a/windows_parse_proto.sh +++ b/windows_parse_proto.sh @@ -5,15 +5,15 @@ fi if [ ! -d "./src/cpp/proto/gradido" ] ; then mkdir ./src/cpp/proto/gradido fi -PROTOC_PATH=./dependencies/grpc/_build/third_party/protobuf/Release -CPP_PLUGIN_PATH=./dependencies/grpc/_build/Release -$PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto +PROTOC_PATH=build/bin +CPP_PLUGIN_PATH=build/bin +$PROTOC_PATH/protoc.exe --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto if [ ! -d "./src/cpp/proto/hedera" ] ; then mkdir ./src/cpp/proto/hedera fi GOOGLE_PROTOBUF_INCLUDES=./dependencies/grpc/third_party/protobuf/src -$PROTOC_PATH/protoc --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto +$PROTOC_PATH/protoc.exe --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto From 5642805b7e2f4f0b253672e82b75b11abd990a5b Mon Sep 17 00:00:00 2001 From: dario Linux Date: Mon, 12 Oct 2020 11:19:55 +0200 Subject: [PATCH 048/195] finish unix makefile updates --- .gitmodules | 3 +++ CMakeLists.txt | 43 ++++++++++++++++++++------------- FindOpenSSL.cmake | 2 ++ dependencies/cmake-modules | 1 + src/cpp/Gradido_LoginServer.cpp | 25 +++++++++++-------- src/cpp/MySQL/Connector.cpp | 19 ++++++++++----- unix_parse_proto.sh | 4 +-- 7 files changed, 62 insertions(+), 35 deletions(-) create mode 160000 dependencies/cmake-modules diff --git a/.gitmodules b/.gitmodules index 7500d3d77..96fdb6a84 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "dependencies/poco"] path = dependencies/poco url = https://github.com/pocoproject/poco.git +[submodule "dependencies/cmake-modules"] + path = dependencies/cmake-modules + url = https://github.com/viaduck/cmake-modules.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 1648b666e..39de3c0c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,11 @@ include_directories( "dependencies/grpc/third_party/protobuf/src" "src/cpp/proto" ) - +#if(WIN32) +#include_directories("dependencies/mariadb-connector-c/include", "dependencies/mariadb-connector-c/build/include") set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") +#endif(WIN32) FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h") @@ -85,10 +87,15 @@ conan_basic_setup() add_executable(Gradido_LoginServer ${LOCAL_SRCS}) - +set(CLIENT_PLUGIN_DIALOG OFF) +set(CLIENT_PLUGIN_client_ed25519 OFF) +set(CLIENT_PLUGIN_MYSQL_CLEAR_PASSWORD OFF) +set(CLIENT_PLUGIN_REMOTE_IO OFF) +set(WITH_SSL OFF) +add_subdirectory("dependencies/mariadb-connector-c") set(DEP_PATH "dependencies") -set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") +#set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") set(GRPC_PATH "${DEP_PATH}/grpc/build") set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types") @@ -126,8 +133,8 @@ if(WIN32) else (WIN32) - - find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) + #find_package(MariaDBClient PATHS "dependencies/cmake-modules") + #find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") list(REMOVE_ITEM CONAN_LIBS "ssl") @@ -138,7 +145,7 @@ else (WIN32) endif(WIN32) # load same ssl version like used from poco -find_package(OpenSSL PATHS . NO_DEFAULT_PATH) +#find_package(OpenSSL PATHS "../" NO_DEFAULT_PATH) find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) @@ -147,11 +154,9 @@ set(CONAN_OPENSSL_CUSTOM_LIBS ${CONAN_OPENSSL_SSL} ${CONAN_OPENSSL_CRYPTO} ) +include_directories(${CONAN_INCLUDE_DIRS_OPENSSL}) +# build grpc -set(BUILD_TESTING OFF) -set(gRPC_SSL_PROVIDER "package") -add_subdirectory("dependencies/grpc/") -message(STATUS "Using gRPC via add_subdirectory.") if(WIN32) @@ -164,14 +169,16 @@ else(WIN32) set(INSTALL_BINDIR "bin") set(INSTALL_PLUGINDIR "bin") - - include_directories( - ${CONAN_INCLUDE_DIRS_OPENSSL} - ) - + target_link_libraries(Gradido_LoginServer ${CONAN_OPENSSL_CUSTOM_LIBS}) endif(WIN32) +set(BUILD_TESTING OFF) +set(gRPC_SSL_PROVIDER "package") +add_subdirectory("dependencies/grpc/") +set(gRPC_SSL_PROVIDER "package") +message(STATUS "Using gRPC via add_subdirectory.") + set(GRPC_LIBS libprotobuf grpc++_reflection grpc++) target_link_libraries(Gradido_LoginServer ${CONAN_LIBS}) @@ -180,12 +187,13 @@ if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) # unix - target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) + target_link_libraries(Gradido_LoginServer libmariadb ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) endif(WIN32) # install if(UNIX) install(TARGETS Gradido_LoginServer RUNTIME DESTINATION /usr/local/bin) +#install(LIBRARYS DESTINATION /usr/local/lib) #install(FILES lib/libmariadb /usr/local/lib) install(FILES DESTINATION lib COMPONENT libmariadb) install(DIRECTORY src/LOCALE DESTINATION /etc/grd_login/ @@ -206,12 +214,13 @@ target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ) + if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) - target_link_libraries(Gradido_LoginServer_Test ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) + target_link_libraries(Gradido_LoginServer_Test libmariadb ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) endif(WIN32) add_test(NAME main COMMAND Gradido_LoginServer_Test) diff --git a/FindOpenSSL.cmake b/FindOpenSSL.cmake index 4a4fec7df..64fefb4ec 100644 --- a/FindOpenSSL.cmake +++ b/FindOpenSSL.cmake @@ -25,6 +25,8 @@ set(OpenSSL_INCLUDE_DIRS "${CONAN_INCLUDE_DIRS_OPENSSL}") set(OpenSSL_INCLUDE_DIR "${CONAN_INCLUDE_DIRS_OPENSSL}") set(OpenSSL_INCLUDES "${CONAN_INCLUDE_DIRS_OPENSSL}") set(OpenSSL_RES_DIRS "${CONAN_RES_DIRS_OPENSSL}") +set(OPENSSL_ROOT_DIR "${CONAN_OPENSSL_ROOT}") +set(OPENSSL_DIR "${CONAN_OPENSSL_ROOT}") set(OpenSSL_DEFINITIONS ) set(OpenSSL_LINKER_FLAGS_LIST "$<$,SHARED_LIBRARY>:>" diff --git a/dependencies/cmake-modules b/dependencies/cmake-modules new file mode 160000 index 000000000..7304f680b --- /dev/null +++ b/dependencies/cmake-modules @@ -0,0 +1 @@ +Subproject commit 7304f680be32915e772466ebddc5b7d3b453abd9 diff --git a/src/cpp/Gradido_LoginServer.cpp b/src/cpp/Gradido_LoginServer.cpp index cf17a0fba..507212e4b 100644 --- a/src/cpp/Gradido_LoginServer.cpp +++ b/src/cpp/Gradido_LoginServer.cpp @@ -31,7 +31,7 @@ -Gradido_LoginServer::Gradido_LoginServer() +Gradido_LoginServer::Gradido_LoginServer() : _helpRequested(false) { } @@ -147,7 +147,7 @@ int Gradido_LoginServer::main(const std::vector& args) unsigned short port = (unsigned short)config().getInt("HTTPServer.port", 9980); unsigned short json_port = (unsigned short)config().getInt("JSONServer.port", 1201); - + //printf("show mnemonic list: \n"); //printf(ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER].getCompleteWordList().data()); if (!ServerConfig::initServerCrypto(config())) { @@ -156,7 +156,7 @@ int Gradido_LoginServer::main(const std::vector& args) return Application::EXIT_CONFIG; } - // first check time for crypto + // first check time for crypto SecretKeyCryptography test_crypto; Profiler timeUsed; if (test_crypto.createKey("email@google.de", "haz27Newpassword") != SecretKeyCryptography::AUTH_CREATE_ENCRYPTION_KEY_SUCCEED) { @@ -178,13 +178,18 @@ int Gradido_LoginServer::main(const std::vector& args) ServerConfig::g_CPUScheduler = new UniLib::controller::CPUSheduler(worker_count, "Default Worker"); ServerConfig::g_CryptoCPUScheduler = new UniLib::controller::CPUSheduler(2, "Crypto Worker"); + // load up connection configs // register MySQL connector - Poco::Data::MySQL::Connector::registerConnector(); - //Poco::Data::MySQL::Connector::KEY; + try { + Poco::Data::MySQL::Connector::registerConnector(); + } catch(Poco::Exception& ex) { + errorLog.error("[Gradido_LoginServer::main] Poco Exception by register MySQL Connector: %s", ex.displayText()); + return Application::EXIT_CONFIG; + } + auto conn = ConnectionManager::getInstance(); - //conn->setConnection() - //printf("try connect login server mysql db\n"); + conn->setConnectionsFromConfig(config(), CONNECTION_MYSQL_LOGIN_SERVER); //printf("try connect php server mysql \n"); //conn->setConnectionsFromConfig(config(), CONNECTION_MYSQL_PHP_SERVER); @@ -196,10 +201,10 @@ int Gradido_LoginServer::main(const std::vector& args) Poco::Net::initializeSSL(); if(!ServerConfig::initSSLClientContext()) { //printf("[Gradido_LoginServer::%s] error init server SSL Client\n", __FUNCTION__); - errorLog.error("[Gradido_LoginServer::main] error init server SSL Client\n"); + errorLog.error("[Gradido_LoginServer::main] error init server SSL Client"); return Application::EXIT_CONFIG; } - + // schedule email verification resend controller::User::checkIfVerificationEmailsShouldBeResend(ServerConfig::g_CronJobsTimer); controller::User::addMissingEmailHashes(); @@ -211,7 +216,7 @@ int Gradido_LoginServer::main(const std::vector& args) Poco::ThreadPool& pool = Poco::ThreadPool::defaultPool(); Poco::Net::HTTPServer srv(new PageRequestHandlerFactory, svs, new Poco::Net::HTTPServerParams); ServerConfig::g_ServerKeySeed->put(7, 918276611); - + // start the HTTPServer srv.start(); diff --git a/src/cpp/MySQL/Connector.cpp b/src/cpp/MySQL/Connector.cpp index dc170cacb..5b35ded21 100644 --- a/src/cpp/MySQL/Connector.cpp +++ b/src/cpp/MySQL/Connector.cpp @@ -48,18 +48,25 @@ const std::string& Connector::name() const Poco::AutoPtr Connector::createSession(const std::string& connectionString, std::size_t timeout) { - return Poco::AutoPtr(new SessionImpl(connectionString, timeout)); + return Poco::AutoPtr(new SessionImpl(connectionString, timeout)); } void Connector::registerConnector() { - if (mysql_library_init(0, 0, 0) != 0) - { - throw Exception("mysql_library_init error"); - } - ServerConfig::g_ServerKeySeed->put(4, DRRandom::r64()); + printf("function pointer address: %d\n", mysql_library_init); + try { + if (mysql_library_init(0, nullptr, nullptr) != 0) + { + throw Exception("mysql_library_init error"); + } + } catch(std::exception &ex) { + printf("mysql exception: \n"); + } + printf("after exception\n"); + ServerConfig::g_ServerKeySeed->put(4, DRRandom::r64()); + printf("instance add new\n"); Poco::Data::SessionFactory::instance().add(new Connector()); } diff --git a/unix_parse_proto.sh b/unix_parse_proto.sh index 3727cc985..43fdc3a14 100755 --- a/unix_parse_proto.sh +++ b/unix_parse_proto.sh @@ -5,8 +5,8 @@ fi if [ ! -d "./src/cpp/proto/gradido" ] ; then mkdir ./src/cpp/proto/gradido fi -PROTOC_PATH=./dependencies/grpc/build/third_party/protobuf -CPP_PLUGIN_PATH=./dependencies/grpc/build +PROTOC_PATH=./build/bin +CPP_PLUGIN_PATH=./build/bin $PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto if [ ! -d "./src/cpp/proto/hedera" ] ; then From 490fbfe6ca5415e540aa57c4951501a81bbb23ab Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Mon, 24 Aug 2020 18:24:48 +0200 Subject: [PATCH 049/195] include grpc manuell in cmake project, debug windows, other configurations are to come --- .gitmodules | 3 + CMakeLists.txt | 359 ++++++++++++++++++++++++----------------------- README | 7 + compile_proto.sh | 6 +- 4 files changed, 194 insertions(+), 181 deletions(-) diff --git a/.gitmodules b/.gitmodules index f61624046..0604a3423 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "dependencies/spirit-po"] path = dependencies/spirit-po url = https://github.com/cbeck88/spirit-po.git +[submodule "dependencies/grpc"] + path = dependencies/grpc + url = https://github.com/grpc/grpc.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a484c3e9..ee09916fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,177 +1,182 @@ -cmake_minimum_required(VERSION 3.0) -project(Gradido_LoginServer C CXX) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin" ) - -SET ( CMAKE_CXX_FLAGS "-std=c++17" ) - -include_directories( - "dependencies" - "dependencies/tinf/src/" - "dependencies/iroha-ed25519/include" - "dependencies/mariadb-connector-c/include" - "dependencies/mariadb-connector-c/build/include" - "dependencies/spirit-po/include" - "src/cpp/proto" - #"dependencies/mariadb-connector-c/build/include" - #"dependencies/mariadb-connector-c/include" - #"import/mariadb/include" -) - - -FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") -FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h") -FILE(GLOB HTTPInterface "src/cpp/HTTPInterface/*.h" "src/cpp/HTTPInterface/*.cpp") -FILE(GLOB JSONInterface "src/cpp/JSONInterface/*.h" "src/cpp/JSONInterface/*.cpp") -FILE(GLOB TASKS "src/cpp/tasks/*.cpp" "src/cpp/tasks/*.h") -FILE(GLOB SINGLETON_MANAGER "src/cpp/SingletonManager/*.h" "src/cpp/SingletonManager/*.cpp") -FILE(GLOB LIB_SRC "src/cpp/lib/*.h" "src/cpp/lib/*.cpp") -FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp") -FILE(GLOB MODEL_TABLE "src/cpp/model/table/*.h" "src/cpp/model/table/*.cpp") -FILE(GLOB MODEL_EMAIL "src/cpp/model/email/*.h" "src/cpp/model/email/*.cpp") -FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp") -FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h") -FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h") -FILE(GLOB PROTO_GRADIDO "src/cpp/proto/gradido/*.cc" "src/cpp/proto/gradido/*.h") -FILE(GLOB PROTO_HEDERA "src/cpp/proto/hedera/*.cc" "src/cpp/proto/hedera/*.h") - -# used only for test project -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") -FILE(GLOB TEST_MODEL "src/cpp/test/model/*.cpp" "src/cpp/test/model/*.h") -FILE(GLOB TEST_MODEL_TABLE "src/cpp/test/model/table/*.cpp" "src/cpp/test/model/table/*.h") -FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controller/*.h") - -SET(LOCAL_SRCS - ${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} - ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} - ${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS} - ${PROTO_GRADIDO} ${PROTO_HEDERA} -) -SET(LOCAL_TEST_SRC - ${TEST} ${TEST_CRYPTO} ${TEST_MODEL} ${TEST_MODEL_TABLE} ${TEST_CONTROLLER} -) -aux_source_directory("src/cpp" LOCAL_SRCS) - -if(MSVC) -# src -source_group("controller" FILES ${CONTROLLER}) -source_group("proto\\gradido" FILES ${PROTO_GRADIDO}) -source_group("proto\\hedera" FILES ${PROTO_HEDERA}) -source_group("tinf" FILES ${TINF}) -source_group("Crypto" FILES ${CRYPTO}) -source_group("tasks" FILES ${TASKS}) -source_group("model\\table" FILES ${MODEL_TABLE}) -source_group("model\\email" FILES ${MODEL_EMAIL}) -source_group("model" FILES ${MODEL}) -source_group("mysql" FILES ${MYSQL}) -source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) -source_group("lib" FILES ${LIB_SRC}) -source_group("HTTP-Interface" FILES ${HTTPInterface}) -source_group("Json-Interface" FILES ${JSONInterface}) -source_group("Test\\crypto" FILES ${TEST_CRYPTO}) -source_group("Test\\model\\table" FILES ${TEST_MODEL_TABLE}) -source_group("Test\\model" FILES ${TEST_MODEL}) -source_group("Test\\controller" FILES ${TEST_CONTROLLER}) -source_group("Test" FILES ${TEST}) -endif(MSVC) - -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup() - -#add_subdirectory("dependencies/curl") -#add_subdirectory("dependencies/mariadb-connector-c") - - -add_executable(Gradido_LoginServer ${LOCAL_SRCS}) -#SUBDIRS("src/test") - -if(WIN32) - -find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-connector-c/build/libmariadb/Release" REQUIRED) -#find_library(MYSQL_LIBRARIES_DEBUG mariadbclient.lib PATHS "import/mariadb/lib/debug") -find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) -find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build/Debug" REQUIRED) -set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") - -#set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") - -#find_library(POCO_DEBUG_FOUNDATION PocoFoundationd PocoFoundation PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_DATA PocoDatad PocoData PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_NET PocoNetd PocoNet PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_NET_SSL PocoNetSSLd PocoNetSSL PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_UTIL PocoUtild PocoUtil PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_CRYPTO PocoCryptod PocoCrypto PATHS ${POCO_DEBUG_PATH} REQUIRED) - -#set(POCO_DEBUG_LIBS ${POCO_DEBUG_FOUNDATION} ${POCO_DEBUG_UTIL} ${POCO_DEBUG_DATA} ${POCO_DEBUG_NET} ${POCO_DEBUG_NET_SSL} ${POCO_DEBUG_CRYPTO}) -#include_directories( -# "I:/FremdCode/C++/poco/Foundation/include" -# "I:/FremdCode/C++/poco/Data/include" -# "I:/FremdCode/C++/poco/Net/include" - #"I:/FremdCode/C++/poco/NetSSL_Win/include" -# "I:/FremdCode/C++/poco/NetSSL_OpenSSL/include" -# "I:/FremdCode/C++/poco/Crypto/include" -# "I:/FremdCode/C++/poco/Util/include" -# "I:/FremdCode/C++/ssl/include" -#) - -set(CMAKE_CXX_FLAGS "/MP /EHsc") -#set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") -#set(CMAKE_CXX_FLAGS_RELEASE "-O3") - -else() - -find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) -# set vars for mariadb cmake files -set(INSTALL_BINDIR "bin") -set(INSTALL_PLUGINDIR "bin") -add_subdirectory("dependencies/mariadb-connector-c") - - -include_directories( - "dependencies/mariadb-connector-c/include" - "build/dependencies/mariadb-connector-c/include" -) - - - -endif() - -target_link_libraries(Gradido_LoginServer ${CONAN_LIBS} ${IROHA_ED25519}) -if(WIN32) -TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) -else() -target_link_libraries(Gradido_LoginServer libmariadb -pthread) -endif() - -# install -if(UNIX) -install(TARGETS Gradido_LoginServer RUNTIME DESTINATION /usr/local/bin) -#install(FILES lib/libmariadb /usr/local/lib) -install(FILES DESTINATION lib COMPONENT libmariadb) -install(DIRECTORY src/LOCALE DESTINATION /etc/grd_login/ - FILES_MATCHING PATTERN "*.po(t)") - - -endif(UNIX) - -enable_testing() - -# ---------------------- Test ----------------------------------------- -#project(Gradido_LoginServer_Test C CXX) -#_TEST_BUILD - - -add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) -target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") - -target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ${IROHA_ED25519}) - -if(WIN32) - TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) - TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) -else() - target_link_libraries(Gradido_LoginServer_Test libmariadb -pthread) -endif() - -add_test(NAME main COMMAND Gradido_LoginServer_Test) +cmake_minimum_required(VERSION 3.0) +project(Gradido_LoginServer C CXX) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin" ) + +SET ( CMAKE_CXX_FLAGS "-std=c++17" ) + +include_directories( + "dependencies" + "dependencies/tinf/src/" + "dependencies/iroha-ed25519/include" + "dependencies/mariadb-connector-c/include" + "dependencies/mariadb-connector-c/build/include" + "dependencies/spirit-po/include" + "dependencies/grpc/include" + "src/cpp/proto" + #"dependencies/mariadb-connector-c/build/include" + #"dependencies/mariadb-connector-c/include" + #"import/mariadb/include" +) + + +FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") +FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h") +FILE(GLOB HTTPInterface "src/cpp/HTTPInterface/*.h" "src/cpp/HTTPInterface/*.cpp") +FILE(GLOB JSONInterface "src/cpp/JSONInterface/*.h" "src/cpp/JSONInterface/*.cpp") +FILE(GLOB TASKS "src/cpp/tasks/*.cpp" "src/cpp/tasks/*.h") +FILE(GLOB SINGLETON_MANAGER "src/cpp/SingletonManager/*.h" "src/cpp/SingletonManager/*.cpp") +FILE(GLOB LIB_SRC "src/cpp/lib/*.h" "src/cpp/lib/*.cpp") +FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp") +FILE(GLOB MODEL_TABLE "src/cpp/model/table/*.h" "src/cpp/model/table/*.cpp") +FILE(GLOB MODEL_EMAIL "src/cpp/model/email/*.h" "src/cpp/model/email/*.cpp") +FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp") +FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h") +FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h") +FILE(GLOB PROTO_GRADIDO "src/cpp/proto/gradido/*.cc" "src/cpp/proto/gradido/*.h") +FILE(GLOB PROTO_HEDERA "src/cpp/proto/hedera/*.cc" "src/cpp/proto/hedera/*.h") + +# used only for test project +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") +FILE(GLOB TEST_MODEL "src/cpp/test/model/*.cpp" "src/cpp/test/model/*.h") +FILE(GLOB TEST_MODEL_TABLE "src/cpp/test/model/table/*.cpp" "src/cpp/test/model/table/*.h") +FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controller/*.h") + +SET(LOCAL_SRCS + ${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} + ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} + ${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS} + ${PROTO_GRADIDO} ${PROTO_HEDERA} +) +SET(LOCAL_TEST_SRC + ${TEST} ${TEST_CRYPTO} ${TEST_MODEL} ${TEST_MODEL_TABLE} ${TEST_CONTROLLER} +) +aux_source_directory("src/cpp" LOCAL_SRCS) + +if(MSVC) +# src +source_group("controller" FILES ${CONTROLLER}) +source_group("proto\\gradido" FILES ${PROTO_GRADIDO}) +source_group("proto\\hedera" FILES ${PROTO_HEDERA}) +source_group("tinf" FILES ${TINF}) +source_group("Crypto" FILES ${CRYPTO}) +source_group("tasks" FILES ${TASKS}) +source_group("model\\table" FILES ${MODEL_TABLE}) +source_group("model\\email" FILES ${MODEL_EMAIL}) +source_group("model" FILES ${MODEL}) +source_group("mysql" FILES ${MYSQL}) +source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) +source_group("lib" FILES ${LIB_SRC}) +source_group("HTTP-Interface" FILES ${HTTPInterface}) +source_group("Json-Interface" FILES ${JSONInterface}) +source_group("Test\\crypto" FILES ${TEST_CRYPTO}) +source_group("Test\\model\\table" FILES ${TEST_MODEL_TABLE}) +source_group("Test\\model" FILES ${TEST_MODEL}) +source_group("Test\\controller" FILES ${TEST_CONTROLLER}) +source_group("Test" FILES ${TEST}) +endif(MSVC) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +#add_subdirectory("dependencies/curl") +#add_subdirectory("dependencies/mariadb-connector-c") + + +add_executable(Gradido_LoginServer ${LOCAL_SRCS}) +#SUBDIRS("src/test") + +if(WIN32) + +find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-connector-c/build/libmariadb/Release" REQUIRED) +#find_library(MYSQL_LIBRARIES_DEBUG mariadbclient.lib PATHS "import/mariadb/lib/debug") +find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) +find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build/Debug" REQUIRED) +set(GRPC_PATH "dependencies/grpc/_build/Debug") +find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) +set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION}) +set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") + +#set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") + +#find_library(POCO_DEBUG_FOUNDATION PocoFoundationd PocoFoundation PATHS ${POCO_DEBUG_PATH} REQUIRED) +#find_library(POCO_DEBUG_DATA PocoDatad PocoData PATHS ${POCO_DEBUG_PATH} REQUIRED) +#find_library(POCO_DEBUG_NET PocoNetd PocoNet PATHS ${POCO_DEBUG_PATH} REQUIRED) +#find_library(POCO_DEBUG_NET_SSL PocoNetSSLd PocoNetSSL PATHS ${POCO_DEBUG_PATH} REQUIRED) +#find_library(POCO_DEBUG_UTIL PocoUtild PocoUtil PATHS ${POCO_DEBUG_PATH} REQUIRED) +#find_library(POCO_DEBUG_CRYPTO PocoCryptod PocoCrypto PATHS ${POCO_DEBUG_PATH} REQUIRED) + +#set(POCO_DEBUG_LIBS ${POCO_DEBUG_FOUNDATION} ${POCO_DEBUG_UTIL} ${POCO_DEBUG_DATA} ${POCO_DEBUG_NET} ${POCO_DEBUG_NET_SSL} ${POCO_DEBUG_CRYPTO}) +#include_directories( +# "I:/FremdCode/C++/poco/Foundation/include" +# "I:/FremdCode/C++/poco/Data/include" +# "I:/FremdCode/C++/poco/Net/include" + #"I:/FremdCode/C++/poco/NetSSL_Win/include" +# "I:/FremdCode/C++/poco/NetSSL_OpenSSL/include" +# "I:/FremdCode/C++/poco/Crypto/include" +# "I:/FremdCode/C++/poco/Util/include" +# "I:/FremdCode/C++/ssl/include" +#) + +set(CMAKE_CXX_FLAGS "/MP /EHsc") +#set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") +#set(CMAKE_CXX_FLAGS_RELEASE "-O3") + +else(WIN32) +find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) +# set vars for mariadb cmake files +set(INSTALL_BINDIR "bin") +set(INSTALL_PLUGINDIR "bin") +add_subdirectory("dependencies/mariadb-connector-c") + + +include_directories( + "dependencies/mariadb-connector-c/include" + "build/dependencies/mariadb-connector-c/include" +) + + + +endif(WIN32) + +target_link_libraries(Gradido_LoginServer ${CONAN_LIBS} ${IROHA_ED25519}) +if(WIN32) +TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) +TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) +TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS}) +else(WIN32) +target_link_libraries(Gradido_LoginServer libmariadb protoc protobuf -pthread) +endif(WIN32) + +# install +if(UNIX) +install(TARGETS Gradido_LoginServer RUNTIME DESTINATION /usr/local/bin) +#install(FILES lib/libmariadb /usr/local/lib) +install(FILES DESTINATION lib COMPONENT libmariadb) +install(DIRECTORY src/LOCALE DESTINATION /etc/grd_login/ + FILES_MATCHING PATTERN "*.po(t)") + + +endif(UNIX) + +enable_testing() + +# ---------------------- Test ----------------------------------------- +#project(Gradido_LoginServer_Test C CXX) +#_TEST_BUILD + + +add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) +target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") + +target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ${IROHA_ED25519}) + +if(WIN32) + TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) +else(WIN32) + target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf -pthread) +endif(WIN32) + +add_test(NAME main COMMAND Gradido_LoginServer_Test) \ No newline at end of file diff --git a/README b/README index f6ca48a88..89783a878 100644 --- a/README +++ b/README @@ -20,6 +20,13 @@ cmake -DWITH_SSL=OFF .. cd ../../../ +cd dependencies/grpc +mkdir _build +cd _build +cmake .. +make +cd ../../../ + # get more dependencies with conan (need conan from https://conan.io/) mkdir build && cd build conan remote add inexor https://api.bintray.com/conan/inexorgame/inexor-conan diff --git a/compile_proto.sh b/compile_proto.sh index 5190ae766..1580a8616 100755 --- a/compile_proto.sh +++ b/compile_proto.sh @@ -6,12 +6,10 @@ if [ ! -d "./src/cpp/proto/gradido" ] ; then mkdir ./src/cpp/proto/gradido fi -protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto +./protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto #if [ ! -d "./src/cpp/proto/hedera" ] ; then # mkdir ./src/cpp/proto/hedera #fi - -#./protoc --cpp_out=./src/cpp/proto/hedera --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto - +./protoc --plugin=protoc-gen-grpc=./grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto From cd355bdd29b39b31ba629109d9d37001fa91a83f Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Tue, 25 Aug 2020 11:26:14 +0200 Subject: [PATCH 050/195] add empty files for hedera proto wrappers --- CMakeLists.txt | 4 +++- dependencies/grpc | 1 + src/cpp/model/hedera/ConsensusCreateTopic.cpp | 0 src/cpp/model/hedera/ConsensusCreateTopic.h | 0 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp | 0 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h | 0 src/cpp/model/hedera/ConsensusSubmitMessage.cpp | 0 src/cpp/model/hedera/ConsensusSubmitMessage.h | 0 src/cpp/model/hedera/Query.cpp | 0 src/cpp/model/hedera/Query.h | 0 src/cpp/model/hedera/QueryHeader.cpp | 0 src/cpp/model/hedera/QueryHeader.h | 0 src/cpp/model/hedera/Response.cpp | 0 src/cpp/model/hedera/Response.h | 0 src/cpp/model/hedera/ResponseHeader.cpp | 0 src/cpp/model/hedera/ResponseHeader.h | 0 src/cpp/model/hedera/Transaction.cpp | 0 src/cpp/model/hedera/Transaction.h | 0 src/cpp/model/hedera/TransactionBody.cpp | 0 src/cpp/model/hedera/TransactionBody.h | 0 20 files changed, 4 insertions(+), 1 deletion(-) create mode 160000 dependencies/grpc create mode 100644 src/cpp/model/hedera/ConsensusCreateTopic.cpp create mode 100644 src/cpp/model/hedera/ConsensusCreateTopic.h create mode 100644 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp create mode 100644 src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h create mode 100644 src/cpp/model/hedera/ConsensusSubmitMessage.cpp create mode 100644 src/cpp/model/hedera/ConsensusSubmitMessage.h create mode 100644 src/cpp/model/hedera/Query.cpp create mode 100644 src/cpp/model/hedera/Query.h create mode 100644 src/cpp/model/hedera/QueryHeader.cpp create mode 100644 src/cpp/model/hedera/QueryHeader.h create mode 100644 src/cpp/model/hedera/Response.cpp create mode 100644 src/cpp/model/hedera/Response.h create mode 100644 src/cpp/model/hedera/ResponseHeader.cpp create mode 100644 src/cpp/model/hedera/ResponseHeader.h create mode 100644 src/cpp/model/hedera/Transaction.cpp create mode 100644 src/cpp/model/hedera/Transaction.h create mode 100644 src/cpp/model/hedera/TransactionBody.cpp create mode 100644 src/cpp/model/hedera/TransactionBody.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ee09916fd..dc8b2fe4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ FILE(GLOB LIB_SRC "src/cpp/lib/*.h" "src/cpp/lib/*.cpp") FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp") FILE(GLOB MODEL_TABLE "src/cpp/model/table/*.h" "src/cpp/model/table/*.cpp") FILE(GLOB MODEL_EMAIL "src/cpp/model/email/*.h" "src/cpp/model/email/*.cpp") +FILE(GLOB MODEL_HEDERA "src/cpp/model/hedera/*.h" "src/cpp/model/hedera/*.cpp") FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp") FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h") FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h") @@ -44,7 +45,7 @@ FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controll SET(LOCAL_SRCS ${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} - ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} + ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_HEDERA} ${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS} ${PROTO_GRADIDO} ${PROTO_HEDERA} ) @@ -63,6 +64,7 @@ source_group("Crypto" FILES ${CRYPTO}) source_group("tasks" FILES ${TASKS}) source_group("model\\table" FILES ${MODEL_TABLE}) source_group("model\\email" FILES ${MODEL_EMAIL}) +source_group("model\\hedera" FILES ${MODEL_HEDERA}) source_group("model" FILES ${MODEL}) source_group("mysql" FILES ${MYSQL}) source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) diff --git a/dependencies/grpc b/dependencies/grpc new file mode 160000 index 000000000..f57a0619b --- /dev/null +++ b/dependencies/grpc @@ -0,0 +1 @@ +Subproject commit f57a0619bc5697ea98c2d5b2c983c7024f43a5db diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.h b/src/cpp/model/hedera/ConsensusCreateTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.cpp b/src/cpp/model/hedera/ConsensusSubmitMessage.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.h b/src/cpp/model/hedera/ConsensusSubmitMessage.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/QueryHeader.cpp b/src/cpp/model/hedera/QueryHeader.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/QueryHeader.h b/src/cpp/model/hedera/QueryHeader.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ResponseHeader.cpp b/src/cpp/model/hedera/ResponseHeader.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ResponseHeader.h b/src/cpp/model/hedera/ResponseHeader.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h new file mode 100644 index 000000000..e69de29bb From a0919dc6c38b5cde1bedc4d7f01be3fea5dec2b6 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Tue, 25 Aug 2020 12:10:02 +0200 Subject: [PATCH 051/195] add nearly empty hedera topic management page, and additional wrapper for hedera proto --- src/cpp/model/hedera/ConsensusDeleteTopic.cpp | 0 src/cpp/model/hedera/ConsensusDeleteTopic.h | 0 src/cpp/model/hedera/ConsensusUpdateTopic.cpp | 0 src/cpp/model/hedera/ConsensusUpdateTopic.h | 0 src/cpsp/adminHederaTopic.cpsp | 21 +++++++++++++++++++ 5 files changed, 21 insertions(+) create mode 100644 src/cpp/model/hedera/ConsensusDeleteTopic.cpp create mode 100644 src/cpp/model/hedera/ConsensusDeleteTopic.h create mode 100644 src/cpp/model/hedera/ConsensusUpdateTopic.cpp create mode 100644 src/cpp/model/hedera/ConsensusUpdateTopic.h create mode 100644 src/cpsp/adminHederaTopic.cpsp diff --git a/src/cpp/model/hedera/ConsensusDeleteTopic.cpp b/src/cpp/model/hedera/ConsensusDeleteTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusDeleteTopic.h b/src/cpp/model/hedera/ConsensusDeleteTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusUpdateTopic.cpp b/src/cpp/model/hedera/ConsensusUpdateTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/ConsensusUpdateTopic.h b/src/cpp/model/hedera/ConsensusUpdateTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpsp/adminHederaTopic.cpsp b/src/cpsp/adminHederaTopic.cpsp new file mode 100644 index 000000000..bc1fcf36e --- /dev/null +++ b/src/cpsp/adminHederaTopic.cpsp @@ -0,0 +1,21 @@ +<%@ page class="AdminHederaTopic" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + + +%> +<%% + const char* pageName = "Admin Hedera Topic"; + + +%><%@ include file="header_old.cpsp" %> +
    +

    Admin Hedera Topic

    + <%= getErrorsHtml() %> + +
    +<%@ include file="footer.cpsp" %> From ec1080c79f5375e8350dd91049c73b82c859f7cd Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Tue, 25 Aug 2020 12:59:34 +0200 Subject: [PATCH 052/195] add new tables and model/table empty files for them --- skeema/gradido_login/crypto_keys.sql | 7 +++++++ skeema/gradido_login/groups.sql | 7 +++++++ skeema/gradido_login/hedera_accounts.sql | 9 +++++++++ skeema/gradido_login/hedera_ids.sql | 7 +++++++ skeema/gradido_login/hedera_topics.sql | 13 +++++++++++++ src/cpp/model/table/CryptoKeys.cpp | 0 src/cpp/model/table/CryptoKeys.h | 0 src/cpp/model/table/Groups.cpp | 0 src/cpp/model/table/Groups.h | 0 src/cpp/model/table/HederaAccounts.cpp | 0 src/cpp/model/table/HederaAccounts.h | 0 src/cpp/model/table/HederaIds.cpp | 0 src/cpp/model/table/HederaIds.h | 0 src/cpp/model/table/HederaTopics.cpp | 0 src/cpp/model/table/HederaTopics.h | 0 15 files changed, 43 insertions(+) create mode 100644 skeema/gradido_login/crypto_keys.sql create mode 100644 skeema/gradido_login/groups.sql create mode 100644 skeema/gradido_login/hedera_accounts.sql create mode 100644 skeema/gradido_login/hedera_ids.sql create mode 100644 skeema/gradido_login/hedera_topics.sql create mode 100644 src/cpp/model/table/CryptoKeys.cpp create mode 100644 src/cpp/model/table/CryptoKeys.h create mode 100644 src/cpp/model/table/Groups.cpp create mode 100644 src/cpp/model/table/Groups.h create mode 100644 src/cpp/model/table/HederaAccounts.cpp create mode 100644 src/cpp/model/table/HederaAccounts.h create mode 100644 src/cpp/model/table/HederaIds.cpp create mode 100644 src/cpp/model/table/HederaIds.h create mode 100644 src/cpp/model/table/HederaTopics.cpp create mode 100644 src/cpp/model/table/HederaTopics.h diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql new file mode 100644 index 000000000..971c56a7b --- /dev/null +++ b/skeema/gradido_login/crypto_keys.sql @@ -0,0 +1,7 @@ +CREATE TABLE `crypto_keys` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `private_key` VARBINARY(64) NOT NULL, + `public_key` BINARY(32) NOT NULL, + `crypto_key_type_id` INT NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/groups.sql b/skeema/gradido_login/groups.sql new file mode 100644 index 000000000..c3d0bc787 --- /dev/null +++ b/skeema/gradido_login/groups.sql @@ -0,0 +1,7 @@ +CREATE TABLE `groups` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `alias` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `description` TEXT NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql new file mode 100644 index 000000000..fc2ad9735 --- /dev/null +++ b/skeema/gradido_login/hedera_accounts.sql @@ -0,0 +1,9 @@ +CREATE TABLE `hedera_accounts` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `user_id` INT UNSIGNED NOT NULL, + `account_hedera_id` INT UNSIGNED NOT NULL, + `account_key_id` INT UNSIGNED NOT NULL, + `balance` BIGINT UNSIGNED NOT NULL DEFAULT '0', + `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/hedera_ids.sql b/skeema/gradido_login/hedera_ids.sql new file mode 100644 index 000000000..624a02207 --- /dev/null +++ b/skeema/gradido_login/hedera_ids.sql @@ -0,0 +1,7 @@ +CREATE TABLE `hedera_ids` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `shardNum` BIGINT NOT NULL DEFAULT '0', + `realmNum` BIGINT NOT NULL DEFAULT '0', + `num` BIGINT NOT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql new file mode 100644 index 000000000..c1fa90f2b --- /dev/null +++ b/skeema/gradido_login/hedera_topics.sql @@ -0,0 +1,13 @@ +CREATE TABLE `hedera_topics` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `topic_hedera_id` INT UNSIGNED NOT NULL, + `auto_renew_account_hedera_id` INT UNSIGNED NULL, + `auto_renew_period` INT UNSIGNED NOT NULL DEFAULT '0', + `group_id` INT UNSIGNED NOT NULL, + `admin_key_id` INT UNSIGNED NULL, + `submit_key_id` INT UNSIGNED NULL, + `current_timeout` BIGINT UNSIGNED NOT NULL DEFAULT '0', + `sequence_number` BIGINT UNSIGNED NULL DEFAULT '0', + `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/model/table/CryptoKeys.cpp b/src/cpp/model/table/CryptoKeys.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/CryptoKeys.h b/src/cpp/model/table/CryptoKeys.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/Groups.cpp b/src/cpp/model/table/Groups.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/Groups.h b/src/cpp/model/table/Groups.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaAccounts.cpp b/src/cpp/model/table/HederaAccounts.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaAccounts.h b/src/cpp/model/table/HederaAccounts.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaIds.cpp b/src/cpp/model/table/HederaIds.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaIds.h b/src/cpp/model/table/HederaIds.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaTopics.cpp b/src/cpp/model/table/HederaTopics.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/table/HederaTopics.h b/src/cpp/model/table/HederaTopics.h new file mode 100644 index 000000000..e69de29bb From 99846b0c61ea576dc72fdc748a7035644e747302 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 16:17:28 +0200 Subject: [PATCH 053/195] rename AuthenticatedEncryption to SecretKeyCryptography --- dependencies/grpc | 2 +- src/cpp/Crypto/KeyPairEd25519.cpp | 4 +- src/cpp/Crypto/KeyPairEd25519.h | 4 +- ...cryption.cpp => SecretKeyCryptography.cpp} | 16 ++-- ...edEncryption.h => SecretKeyCryptography.h} | 14 ++-- src/cpp/controller/User.cpp | 10 +-- src/cpp/controller/User.h | 6 +- .../AuthenticatedEncryptionCreateKeyTask.cpp | 78 +++++++++---------- .../crypto/TestAuthenticatedEncryption.cpp | 10 +-- 9 files changed, 72 insertions(+), 72 deletions(-) rename src/cpp/Crypto/{AuthenticatedEncryption.cpp => SecretKeyCryptography.cpp} (86%) rename src/cpp/Crypto/{AuthenticatedEncryption.h => SecretKeyCryptography.h} (85%) diff --git a/dependencies/grpc b/dependencies/grpc index f57a0619b..7d7e45676 160000 --- a/dependencies/grpc +++ b/dependencies/grpc @@ -1 +1 @@ -Subproject commit f57a0619bc5697ea98c2d5b2c983c7024f43a5db +Subproject commit 7d7e4567625db7cfebf8969a225948097a3f9f89 diff --git a/src/cpp/Crypto/KeyPairEd25519.cpp b/src/cpp/Crypto/KeyPairEd25519.cpp index ee8cabfa0..392bf5e8e 100644 --- a/src/cpp/Crypto/KeyPairEd25519.cpp +++ b/src/cpp/Crypto/KeyPairEd25519.cpp @@ -151,13 +151,13 @@ MemoryBin* KeyPairEd25519::sign(const unsigned char* message, size_t messageSize } -MemoryBin* KeyPairEd25519::getCryptedPrivKey(const Poco::AutoPtr password) const +MemoryBin* KeyPairEd25519::getCryptedPrivKey(const Poco::AutoPtr password) const { if (password.isNull()) return nullptr; if (!mSodiumSecret) return nullptr; MemoryBin* encryptedKey = nullptr; - if (AuthenticatedEncryption::AUTH_ENCRYPT_OK == password->encrypt(mSodiumSecret, &encryptedKey)) { + if (SecretKeyCryptography::AUTH_ENCRYPT_OK == password->encrypt(mSodiumSecret, &encryptedKey)) { return encryptedKey; } else { diff --git a/src/cpp/Crypto/KeyPairEd25519.h b/src/cpp/Crypto/KeyPairEd25519.h index 7b3f11d4b..75a1ce9f1 100644 --- a/src/cpp/Crypto/KeyPairEd25519.h +++ b/src/cpp/Crypto/KeyPairEd25519.h @@ -13,7 +13,7 @@ #include "sodium.h" -#include "AuthenticatedEncryption.h" +#include "SecretKeyCryptography.h" #include "Passphrase.h" class KeyPairEd25519 : public IKeyPair @@ -63,7 +63,7 @@ public: inline bool hasPrivateKey() const { return mSodiumSecret != nullptr; } //! \brief only way to get a private key.. encrypted - MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; + MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; protected: diff --git a/src/cpp/Crypto/AuthenticatedEncryption.cpp b/src/cpp/Crypto/SecretKeyCryptography.cpp similarity index 86% rename from src/cpp/Crypto/AuthenticatedEncryption.cpp rename to src/cpp/Crypto/SecretKeyCryptography.cpp index 421537a66..0685ecaff 100644 --- a/src/cpp/Crypto/AuthenticatedEncryption.cpp +++ b/src/cpp/Crypto/SecretKeyCryptography.cpp @@ -1,22 +1,22 @@ -#include "AuthenticatedEncryption.h" +#include "SecretKeyCryptography.h" #include "sodium.h" #include "../ServerConfig.h" #include #include "../lib/Profiler.h" -AuthenticatedEncryption::AuthenticatedEncryption() +SecretKeyCryptography::SecretKeyCryptography() : mOpsLimit(10), mMemLimit(33554432), mAlgo(2), mEncryptionKey(nullptr), mEncryptionKeyHash(0) { } -AuthenticatedEncryption::AuthenticatedEncryption(unsigned long long opslimit, size_t memlimit, int algo) +SecretKeyCryptography::SecretKeyCryptography(unsigned long long opslimit, size_t memlimit, int algo) : mOpsLimit(opslimit), mMemLimit(memlimit), mAlgo(algo), mEncryptionKey(nullptr), mEncryptionKeyHash(0) { } -AuthenticatedEncryption::~AuthenticatedEncryption() +SecretKeyCryptography::~SecretKeyCryptography() { if (mEncryptionKey) { MemoryManager::getInstance()->releaseMemory(mEncryptionKey); @@ -24,7 +24,7 @@ AuthenticatedEncryption::~AuthenticatedEncryption() } } -AuthenticatedEncryption::ResultType AuthenticatedEncryption::createKey(const std::string& salt_parameter, const std::string& passwd) +SecretKeyCryptography::ResultType SecretKeyCryptography::createKey(const std::string& salt_parameter, const std::string& passwd) { assert(crypto_hash_sha512_BYTES >= crypto_pwhash_SALTBYTES); @@ -79,7 +79,7 @@ AuthenticatedEncryption::ResultType AuthenticatedEncryption::createKey(const std return AUTH_ENCRYPT_OK; } -AuthenticatedEncryption::ResultType AuthenticatedEncryption::encrypt(const MemoryBin* message, MemoryBin** encryptedMessage) const +SecretKeyCryptography::ResultType SecretKeyCryptography::encrypt(const MemoryBin* message, MemoryBin** encryptedMessage) const { assert(message && encryptedMessage); std::shared_lock _lock(mWorkingMutex); @@ -111,7 +111,7 @@ AuthenticatedEncryption::ResultType AuthenticatedEncryption::encrypt(const Memor return AUTH_ENCRYPT_OK; } -AuthenticatedEncryption::ResultType AuthenticatedEncryption::decrypt(const unsigned char* encryptedMessage, size_t encryptedMessageSize, MemoryBin** message) const +SecretKeyCryptography::ResultType SecretKeyCryptography::decrypt(const unsigned char* encryptedMessage, size_t encryptedMessageSize, MemoryBin** message) const { assert(message); std::shared_lock _lock(mWorkingMutex); @@ -139,7 +139,7 @@ AuthenticatedEncryption::ResultType AuthenticatedEncryption::decrypt(const unsig return AUTH_DECRYPT_OK; } -const char* AuthenticatedEncryption::getErrorMessage(ResultType type) +const char* SecretKeyCryptography::getErrorMessage(ResultType type) { switch (type) { case AUTH_ENCRYPT_OK: return "everything is ok"; diff --git a/src/cpp/Crypto/AuthenticatedEncryption.h b/src/cpp/Crypto/SecretKeyCryptography.h similarity index 85% rename from src/cpp/Crypto/AuthenticatedEncryption.h rename to src/cpp/Crypto/SecretKeyCryptography.h index a19e0f856..0a0a16072 100644 --- a/src/cpp/Crypto/AuthenticatedEncryption.h +++ b/src/cpp/Crypto/SecretKeyCryptography.h @@ -17,13 +17,13 @@ * * \date: 07-06-2020 * - * \brief: Wrapper Class for make using libsodium authenticated encryption easy, used for encrypt private keys for user + * \brief: Wrapper Class for make using libsodium secret key encryption easy, used for encrypt private keys for user with pwhash * */ typedef Poco::UInt64 KeyHashed; -class AuthenticatedEncryption : public AutoPtrContainer +class SecretKeyCryptography : public AutoPtrContainer { public: @@ -37,20 +37,20 @@ public: }; //! \brief init with default algorithms parameter - AuthenticatedEncryption(); + SecretKeyCryptography(); //! \brief init with custom algorithms parameter //! //! details see in libsodium crypto_pwhash - AuthenticatedEncryption(unsigned long long opslimit, size_t memlimit, int algo); + SecretKeyCryptography(unsigned long long opslimit, size_t memlimit, int algo); - ~AuthenticatedEncryption(); + ~SecretKeyCryptography(); inline KeyHashed getKeyHashed() const { std::shared_lock _lock(mWorkingMutex); return mEncryptionKeyHash; } - inline bool operator == (const Poco::AutoPtr& b) const { + inline bool operator == (const Poco::AutoPtr& b) const { return isTheSame(b); } - inline bool isTheSame(const Poco::AutoPtr& b) const { + inline bool isTheSame(const Poco::AutoPtr& b) const { std::shared_lock _lock(mWorkingMutex); if (b.isNull()) return false; return mEncryptionKeyHash == b->getKeyHashed(); diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 7aedbb701..32a3ab700 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -144,7 +144,7 @@ namespace controller { return -3; } observer->addTask(email_hash, TASK_OBSERVER_PASSWORD_CREATION); - Poco::AutoPtr authenticated_encryption(new AuthenticatedEncryption); + Poco::AutoPtr authenticated_encryption(new SecretKeyCryptography); assert(!authenticated_encryption.isNull() && model); authenticated_encryption->createKey(model->getEmail(), password); @@ -163,7 +163,7 @@ namespace controller { } else { - if (AuthenticatedEncryption::AUTH_DECRYPT_OK == authenticated_encryption->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { + if (SecretKeyCryptography::AUTH_DECRYPT_OK == authenticated_encryption->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { if (mGradidoKeyPair) { if (mGradidoKeyPair->isTheSame(clear_private_key) == 0) { mCanDecryptPrivateKey = true; @@ -225,7 +225,7 @@ namespace controller { auto email_hash = observer->makeHash(model->getEmail()); observer->addTask(email_hash, TASK_OBSERVER_PASSWORD_CREATION); - Poco::AutoPtr authenticated_encryption(new AuthenticatedEncryption); + Poco::AutoPtr authenticated_encryption(new SecretKeyCryptography); assert(!authenticated_encryption.isNull() && model); authenticated_encryption->createKey(model->getEmail(), password); @@ -234,7 +234,7 @@ namespace controller { } - int User::setNewPassword(Poco::AutoPtr passwd) + int User::setNewPassword(Poco::AutoPtr passwd) { std::unique_lock _lock(mSharedMutex); auto model = getModel(); @@ -249,7 +249,7 @@ namespace controller { if ((!mGradidoKeyPair || !mGradidoKeyPair->hasPrivateKey()) && model->hasPrivateKeyEncrypted()) { //if (!mGradidoKeyPair) mGradidoKeyPair = new KeyPairEd25519; MemoryBin* clear_private_key = nullptr; - if (AuthenticatedEncryption::AUTH_DECRYPT_OK == mPassword->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { + if (SecretKeyCryptography::AUTH_DECRYPT_OK == mPassword->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) { if (mGradidoKeyPair && mGradidoKeyPair->isTheSame(clear_private_key) != 0) { delete mGradidoKeyPair; diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index 33daa9eda..5eb7c8ef6 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -80,7 +80,7 @@ namespace controller { //! \return 1 = password changed, private key re-encrypted and saved into db //! \return 2 = password changed, only hash stored in db, couldn't load private key for re-encryption //! \return -1 = stored pubkey and private key didn't match - int setNewPassword(Poco::AutoPtr passwd); + int setNewPassword(Poco::AutoPtr passwd); //! \brief set authenticated encryption and save hash in db, also re encrypt private key if exist @@ -92,7 +92,7 @@ namespace controller { int setNewPassword(const std::string& password); //! \brief return AuthenticatedEncryption Auto Pointer - inline const Poco::AutoPtr getPassword() { + inline const Poco::AutoPtr getPassword() { std::shared_lock _lock(mSharedMutex); return mPassword; } @@ -128,7 +128,7 @@ namespace controller { std::string mPublicHex; - Poco::AutoPtr mPassword; + Poco::AutoPtr mPassword; KeyPairEd25519* mGradidoKeyPair; bool mCanDecryptPrivateKey; diff --git a/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp b/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp index fa8048e6a..9cc2338a1 100644 --- a/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp +++ b/src/cpp/tasks/AuthenticatedEncryptionCreateKeyTask.cpp @@ -1,40 +1,40 @@ -#include "AuthenticatedEncryptionCreateKeyTask.h" - -#include "../ServerConfig.h" -#include "../SingletonManager/SingletonTaskObserver.h" -#include "../SingletonManager/ErrorManager.h" - -#include "../lib/Profiler.h" - -AuthenticatedEncryptionCreateKeyTask::AuthenticatedEncryptionCreateKeyTask(Poco::AutoPtr user, const std::string& passwd) - : UniLib::controller::CPUTask(ServerConfig::g_CryptoCPUScheduler), mUser(user), mPassword(passwd) -{ - assert(!mUser.isNull()); - SingletonTaskObserver::getInstance()->addTask(mUser->getModel()->getEmail(), TASK_OBSERVER_PASSWORD_CREATION); -} - -AuthenticatedEncryptionCreateKeyTask::~AuthenticatedEncryptionCreateKeyTask() -{ - SingletonTaskObserver::getInstance()->removeTask(mUser->getModel()->getEmail(), TASK_OBSERVER_PASSWORD_CREATION); -} - -int AuthenticatedEncryptionCreateKeyTask::run() -{ - auto em = ErrorManager::getInstance(); - const static char* function_name = "AuthenticatedEncryptionCreateKeyTask::run"; - auto authenticated_encryption = new AuthenticatedEncryption; - Profiler timeUsed; - if (AuthenticatedEncryption::AUTH_ENCRYPT_OK != authenticated_encryption->createKey(mUser->getModel()->getEmail(), mPassword)) { - em->addError(new Error(function_name, "error creating key")); - em->addError(new ParamError(function_name, "for email", mUser->getModel()->getEmail())); - em->addError(new ParamError(function_name, "strerror: ", strerror(errno))); - em->sendErrorsAsEmail(); - return -1; - } - //printf("create password time: %s\n", timeUsed.string().data()); - timeUsed.reset(); - mUser->setNewPassword(authenticated_encryption); - //printf("set password time: %s\n", timeUsed.string().data()); - - return 0; +#include "AuthenticatedEncryptionCreateKeyTask.h" + +#include "../ServerConfig.h" +#include "../SingletonManager/SingletonTaskObserver.h" +#include "../SingletonManager/ErrorManager.h" + +#include "../lib/Profiler.h" + +AuthenticatedEncryptionCreateKeyTask::AuthenticatedEncryptionCreateKeyTask(Poco::AutoPtr user, const std::string& passwd) + : UniLib::controller::CPUTask(ServerConfig::g_CryptoCPUScheduler), mUser(user), mPassword(passwd) +{ + assert(!mUser.isNull()); + SingletonTaskObserver::getInstance()->addTask(mUser->getModel()->getEmail(), TASK_OBSERVER_PASSWORD_CREATION); +} + +AuthenticatedEncryptionCreateKeyTask::~AuthenticatedEncryptionCreateKeyTask() +{ + SingletonTaskObserver::getInstance()->removeTask(mUser->getModel()->getEmail(), TASK_OBSERVER_PASSWORD_CREATION); +} + +int AuthenticatedEncryptionCreateKeyTask::run() +{ + auto em = ErrorManager::getInstance(); + const static char* function_name = "AuthenticatedEncryptionCreateKeyTask::run"; + auto authenticated_encryption = new SecretKeyCryptography; + Profiler timeUsed; + if (SecretKeyCryptography::AUTH_ENCRYPT_OK != authenticated_encryption->createKey(mUser->getModel()->getEmail(), mPassword)) { + em->addError(new Error(function_name, "error creating key")); + em->addError(new ParamError(function_name, "for email", mUser->getModel()->getEmail())); + em->addError(new ParamError(function_name, "strerror: ", strerror(errno))); + em->sendErrorsAsEmail(); + return -1; + } + printf("create password time: %s\n", timeUsed.string().data()); + timeUsed.reset(); + mUser->setNewPassword(authenticated_encryption); + printf("set password time: %s\n", timeUsed.string().data()); + + return 0; } \ No newline at end of file diff --git a/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp b/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp index 93c19bc9b..e863e773d 100644 --- a/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp +++ b/src/cpp/test/crypto/TestAuthenticatedEncryption.cpp @@ -1,6 +1,6 @@ #include "TestAuthenticatedEncryption.h" -#include "../../Crypto/AuthenticatedEncryption.h" +#include "../../Crypto/SecretKeyCryptography.h" #include "../../lib/Profiler.h" #include "../../lib/DataTypeConverter.h" @@ -12,12 +12,12 @@ void TestAuthenticatedEncryption::SetUp() } TEST_F(TestAuthenticatedEncryption, encryptDecryptTest) { - AuthenticatedEncryption authenticated_encryption; + SecretKeyCryptography authenticated_encryption; EXPECT_FALSE(authenticated_encryption.hasKey()); EXPECT_EQ(authenticated_encryption.getKeyHashed(), 0); Profiler time_used; - EXPECT_EQ(authenticated_encryption.createKey("dariofrodo@gmx.de", "r3an7d_spassw"), AuthenticatedEncryption::AUTH_ENCRYPT_OK); + EXPECT_EQ(authenticated_encryption.createKey("dariofrodo@gmx.de", "r3an7d_spassw"), SecretKeyCryptography::AUTH_ENCRYPT_OK); printf("create key duration: %s\n", time_used.string().data()); EXPECT_TRUE(authenticated_encryption.hasKey()); @@ -29,12 +29,12 @@ TEST_F(TestAuthenticatedEncryption, encryptDecryptTest) { memcpy(*test_message_bin, test_message.data(), test_message.size()); time_used.reset(); - EXPECT_EQ(authenticated_encryption.encrypt(test_message_bin, &encrypted_message), AuthenticatedEncryption::AUTH_ENCRYPT_OK); + EXPECT_EQ(authenticated_encryption.encrypt(test_message_bin, &encrypted_message), SecretKeyCryptography::AUTH_ENCRYPT_OK); printf("encrypt message duration: %s\n", time_used.string().data()); MemoryBin* decrypted_message = nullptr; time_used.reset(); - EXPECT_EQ(authenticated_encryption.decrypt(encrypted_message, &decrypted_message), AuthenticatedEncryption::AUTH_DECRYPT_OK); + EXPECT_EQ(authenticated_encryption.decrypt(encrypted_message, &decrypted_message), SecretKeyCryptography::AUTH_DECRYPT_OK); printf("decrypt message duration: %s\n", time_used.string().data()); EXPECT_EQ(std::string((const char*)*decrypted_message, decrypted_message->size()), test_message); From fbc058cf82381b471183deefd4dc41dc7078cc7e Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 16:18:38 +0200 Subject: [PATCH 054/195] add binToHex with Poco::Nullable for easy use with public keys --- src/cpp/lib/DataTypeConverter.cpp | 10 ++++++++++ src/cpp/lib/DataTypeConverter.h | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index c3275ba49..a97cb8d0e 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -176,6 +176,16 @@ namespace DataTypeConverter return hexString; } + std::string binToHex(const Poco::Nullable& nullableBin) + { + if (nullableBin.isNull()) { + return "0x0"; + } + else { + return binToHex(nullableBin.value().content().data(), nullableBin.value().content().size()); + } + } + std::string pubkeyToHex(const unsigned char* pubkey) { auto mm = MemoryManager::getInstance(); diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index e1a419a93..46a767d97 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -5,9 +5,10 @@ #include "../SingletonManager/MemoryManager.h" #include "Poco/Timespan.h" +#include "Poco/Nullable.h" +#include "Poco/Data/LOB.h" #include "../SingletonManager/LanguageManager.h" - namespace DataTypeConverter { enum NumberParseState @@ -26,7 +27,9 @@ namespace DataTypeConverter { std::string binToBase64(const MemoryBin* data); + std::string binToHex(const unsigned char* data, size_t size); + std::string binToHex(const Poco::Nullable& nullableBin); inline std::string binToHex(const MemoryBin* data) { return binToHex(data->data(), data->size());} //! \param pubkey pointer to array with crypto_sign_PUBLICKEYBYTES size From 559795a4897c305caf151766c9466f985ee8a794 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 17:13:49 +0200 Subject: [PATCH 055/195] update skeema files, fill in empty model table classes for new mysql tables --- skeema/gradido_login/crypto_keys.sql | 12 ++-- skeema/gradido_login/elopage_buys.sql | 8 +-- skeema/gradido_login/email_opt_in.sql | 8 +-- skeema/gradido_login/email_opt_in_types.sql | 2 +- skeema/gradido_login/groups.sql | 15 ++--- skeema/gradido_login/hedera_accounts.sql | 18 +++--- skeema/gradido_login/hedera_ids.sql | 14 ++--- skeema/gradido_login/hedera_topics.sql | 25 ++++---- skeema/gradido_login/roles.sql | 4 +- skeema/gradido_login/user_backups.sql | 2 +- skeema/gradido_login/user_roles.sql | 2 +- skeema/gradido_login/users.sql | 32 +++++----- src/cpp/model/table/CryptoKeys.cpp | 70 +++++++++++++++++++++ src/cpp/model/table/CryptoKeys.h | 43 +++++++++++++ src/cpp/model/table/Groups.cpp | 57 +++++++++++++++++ src/cpp/model/table/Groups.h | 35 +++++++++++ src/cpp/model/table/HederaAccounts.cpp | 63 +++++++++++++++++++ src/cpp/model/table/HederaAccounts.h | 36 +++++++++++ src/cpp/model/table/HederaIds.cpp | 58 +++++++++++++++++ src/cpp/model/table/HederaIds.h | 36 +++++++++++ src/cpp/model/table/HederaTopics.cpp | 69 ++++++++++++++++++++ src/cpp/model/table/HederaTopics.h | 41 ++++++++++++ 22 files changed, 581 insertions(+), 69 deletions(-) diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index 971c56a7b..43b511db2 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,7 +1,7 @@ CREATE TABLE `crypto_keys` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `private_key` VARBINARY(64) NOT NULL, - `public_key` BINARY(32) NOT NULL, - `crypto_key_type_id` INT NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `id` int unsigned NOT NULL AUTO_INCREMENT, + `private_key` varbinary(64) NOT NULL, + `public_key` binary(32) NOT NULL, + `crypto_key_type_id` int NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/elopage_buys.sql b/skeema/gradido_login/elopage_buys.sql index be3464846..0be79a34b 100644 --- a/skeema/gradido_login/elopage_buys.sql +++ b/skeema/gradido_login/elopage_buys.sql @@ -1,15 +1,15 @@ CREATE TABLE `elopage_buys` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `elopage_user_id` int NOT NULL, `affiliate_program_id` int NOT NULL, `publisher_id` int NOT NULL, `order_id` int NOT NULL, `product_id` int NOT NULL, `product_price` int NOT NULL, - `payer_email` varchar(255) COLLATE utf8_bin NOT NULL, - `publisher_email` varchar(255) COLLATE utf8_bin NOT NULL, + `payer_email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `publisher_email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `payed` tinyint NOT NULL, `success_date` datetime NOT NULL, - `event` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `event` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/email_opt_in.sql b/skeema/gradido_login/email_opt_in.sql index 1589093e8..da4288475 100644 --- a/skeema/gradido_login/email_opt_in.sql +++ b/skeema/gradido_login/email_opt_in.sql @@ -1,11 +1,11 @@ CREATE TABLE `email_opt_in` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `verification_code` bigint unsigned NOT NULL, `email_opt_in_type_id` int NOT NULL, - `created` datetime NOT NULL DEFAULT current_timestamp(), - `resend_count` int DEFAULT 0, - `updated` DATETIME on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `resend_count` int DEFAULT '0', + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `verification_code` (`verification_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/email_opt_in_types.sql b/skeema/gradido_login/email_opt_in_types.sql index f46275727..dbcd2d272 100644 --- a/skeema/gradido_login/email_opt_in_types.sql +++ b/skeema/gradido_login/email_opt_in_types.sql @@ -1,5 +1,5 @@ CREATE TABLE `email_opt_in_types` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` varchar(255) NOT NULL, PRIMARY KEY (`id`) diff --git a/skeema/gradido_login/groups.sql b/skeema/gradido_login/groups.sql index c3d0bc787..8c5e143bb 100644 --- a/skeema/gradido_login/groups.sql +++ b/skeema/gradido_login/groups.sql @@ -1,7 +1,8 @@ -CREATE TABLE `groups` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `alias` VARCHAR(255) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `description` TEXT NULL DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file +CREATE TABLE `groups` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `alias` varchar(190) NOT NULL, + `name` varchar(255) NOT NULL, + `description` text, + PRIMARY KEY (`id`), + UNIQUE KEY `alias` (`alias`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql index fc2ad9735..23ffa33d1 100644 --- a/skeema/gradido_login/hedera_accounts.sql +++ b/skeema/gradido_login/hedera_accounts.sql @@ -1,9 +1,11 @@ CREATE TABLE `hedera_accounts` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `user_id` INT UNSIGNED NOT NULL, - `account_hedera_id` INT UNSIGNED NOT NULL, - `account_key_id` INT UNSIGNED NOT NULL, - `balance` BIGINT UNSIGNED NOT NULL DEFAULT '0', - `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL, + `account_hedera_id` int unsigned NOT NULL, + `account_key_id` int unsigned NOT NULL, + `balance` bigint unsigned NOT NULL DEFAULT '0', + `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `account_hedera_id` (`account_hedera_id`), + UNIQUE KEY `account_key_id` (`account_key_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/hedera_ids.sql b/skeema/gradido_login/hedera_ids.sql index 624a02207..b5fd26682 100644 --- a/skeema/gradido_login/hedera_ids.sql +++ b/skeema/gradido_login/hedera_ids.sql @@ -1,7 +1,7 @@ -CREATE TABLE `hedera_ids` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `shardNum` BIGINT NOT NULL DEFAULT '0', - `realmNum` BIGINT NOT NULL DEFAULT '0', - `num` BIGINT NOT NULL, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file +CREATE TABLE `hedera_ids` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `shardNum` bigint NOT NULL DEFAULT '0', + `realmNum` bigint NOT NULL DEFAULT '0', + `num` bigint NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index c1fa90f2b..6a58174c1 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -1,13 +1,14 @@ CREATE TABLE `hedera_topics` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `topic_hedera_id` INT UNSIGNED NOT NULL, - `auto_renew_account_hedera_id` INT UNSIGNED NULL, - `auto_renew_period` INT UNSIGNED NOT NULL DEFAULT '0', - `group_id` INT UNSIGNED NOT NULL, - `admin_key_id` INT UNSIGNED NULL, - `submit_key_id` INT UNSIGNED NULL, - `current_timeout` BIGINT UNSIGNED NOT NULL DEFAULT '0', - `sequence_number` BIGINT UNSIGNED NULL DEFAULT '0', - `updated` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `id` int unsigned NOT NULL AUTO_INCREMENT, + `topic_hedera_id` int unsigned NOT NULL, + `auto_renew_account_hedera_id` int unsigned DEFAULT NULL, + `auto_renew_period` int unsigned NOT NULL DEFAULT '0', + `group_id` int unsigned NOT NULL, + `admin_key_id` int unsigned DEFAULT NULL, + `submit_key_id` int unsigned DEFAULT NULL, + `current_timeout` timestamp NOT NULL DEFAULT '0', + `sequence_number` bigint unsigned DEFAULT '0', + `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `topic_hedera_id` (`topic_hedera_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/roles.sql b/skeema/gradido_login/roles.sql index b9d51dd11..c99223961 100644 --- a/skeema/gradido_login/roles.sql +++ b/skeema/gradido_login/roles.sql @@ -1,7 +1,7 @@ CREATE TABLE `roles` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` varchar(255) NOT NULL, - `flags` bigint NOT NULL DEFAULT 0, + `flags` bigint NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/user_backups.sql b/skeema/gradido_login/user_backups.sql index 699c9a2c6..7e3b7d85a 100644 --- a/skeema/gradido_login/user_backups.sql +++ b/skeema/gradido_login/user_backups.sql @@ -1,5 +1,5 @@ CREATE TABLE `user_backups` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `passphrase` text NOT NULL, `mnemonic_type` int DEFAULT '-1', diff --git a/skeema/gradido_login/user_roles.sql b/skeema/gradido_login/user_roles.sql index ac9f0834c..a92154ce8 100644 --- a/skeema/gradido_login/user_roles.sql +++ b/skeema/gradido_login/user_roles.sql @@ -1,5 +1,5 @@ CREATE TABLE `user_roles` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL, `role_id` int NOT NULL, PRIMARY KEY (`id`) diff --git a/skeema/gradido_login/users.sql b/skeema/gradido_login/users.sql index 6c3eb5b82..e3c7deec5 100644 --- a/skeema/gradido_login/users.sql +++ b/skeema/gradido_login/users.sql @@ -1,16 +1,16 @@ -CREATE TABLE `users` ( - `id` int UNSIGNED NOT NULL AUTO_INCREMENT, - `email` varchar(191) NOT NULL, - `first_name` varchar(150) NOT NULL, - `last_name` varchar(255) DEFAULT '', - `password` bigint unsigned DEFAULT 0, - `pubkey` binary(32) DEFAULT NULL, - `privkey` binary(80) DEFAULT NULL, - `created` datetime NOT NULL DEFAULT current_timestamp(), - `email_checked` tinyint NOT NULL DEFAULT 0, - `passphrase_shown` tinyint NOT NULL DEFAULT 0, - `language` varchar(4) NOT NULL DEFAULT 'de', - `disabled` BOOLEAN NULL DEFAULT FALSE, - PRIMARY KEY (`id`), - UNIQUE KEY `email` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +CREATE TABLE `users` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `email` varchar(191) NOT NULL, + `first_name` varchar(150) NOT NULL, + `last_name` varchar(255) DEFAULT '', + `password` bigint unsigned NOT NULL, + `pubkey` binary(32) DEFAULT NULL, + `privkey` binary(80) DEFAULT NULL, + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `email_checked` tinyint NOT NULL DEFAULT '0', + `passphrase_shown` tinyint NOT NULL DEFAULT '0', + `language` varchar(4) NOT NULL DEFAULT 'de', + `disabled` tinyint DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `email` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/model/table/CryptoKeys.cpp b/src/cpp/model/table/CryptoKeys.cpp index e69de29bb..e159f51cc 100644 --- a/src/cpp/model/table/CryptoKeys.cpp +++ b/src/cpp/model/table/CryptoKeys.cpp @@ -0,0 +1,70 @@ +#include "CryptoKeys.h" +#include "../../lib/DataTypeConverter.h" +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + CryptoKeys::CryptoKeys() + { + + } + + CryptoKeys::~CryptoKeys() + { + + } + + std::string CryptoKeys::toString() + { + assert(mKeyType < KEY_TYPE_COUNT && mKeyType >= 0); + std::stringstream ss; + ss << "Key Type: " << typeToString(static_cast(mKeyType)) << std::endl; + ss << "Public Key: " << DataTypeConverter::binToHex(mPublicKey); + return ss.str(); + } + + + const char* CryptoKeys::typeToString(KeyType type) + { + switch (type) { + case KEY_TYPE_ED25519_REF10: return "ed25519 ref10"; + case KEY_TYPE_SODIUM_ED25519: return "sodium ed22519"; + } + return ""; + } + + Poco::Data::Statement CryptoKeys::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, private_key, public_key, crypto_key_type_id FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mPrivateKey), into(mPublicKey), into(mKeyType); + + return select; + } + + Poco::Data::Statement CryptoKeys::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where public_key = ?" + , into(mID), use(mPublicKey); + unlock(); + return select; + } + + + Poco::Data::Statement CryptoKeys::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (private_key, public_key, crypto_key_type_id) VALUES(?,?,?)" + , use(mPrivateKey), use(mPublicKey), use(mKeyType); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKeys.h b/src/cpp/model/table/CryptoKeys.h index e69de29bb..15991c70b 100644 --- a/src/cpp/model/table/CryptoKeys.h +++ b/src/cpp/model/table/CryptoKeys.h @@ -0,0 +1,43 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE + +#include "ModelBase.h" +#include "Poco/Types.h" + +namespace model { + namespace table { + + enum KeyType { + KEY_TYPE_SODIUM_ED25519, + KEY_TYPE_ED25519_REF10, + KEY_TYPE_COUNT + }; + + class CryptoKeys : public ModelBase + { + public: + CryptoKeys(); + ~CryptoKeys(); + + // generic db operations + const char* getTableName() const { return "crypto_keys"; } + std::string toString(); + + + static const char* typeToString(KeyType type); + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + Poco::Nullable mPrivateKey; + Poco::Nullable mPublicKey; + int mKeyType; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/Groups.cpp b/src/cpp/model/table/Groups.cpp index e69de29bb..e99780783 100644 --- a/src/cpp/model/table/Groups.cpp +++ b/src/cpp/model/table/Groups.cpp @@ -0,0 +1,57 @@ +#include "Groups.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + Groups::Groups() + { + } + + Groups::~Groups() + { + + } + + std::string Groups::toString() + { + std::stringstream ss; + ss << "Alias: " << mAlias << std::endl; + ss << "Name: " << mName << std::endl; + ss << "Description:" << mDescription << std::endl; + return ss.str(); + } + + Poco::Data::Statement Groups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, alias, name, description FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mAlias), into(mName), into(mDescription); + + return select; + } + Poco::Data::Statement Groups::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where alias = ?" + , into(mID), use(mAlias); + unlock(); + return select; + + } + Poco::Data::Statement Groups::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (alias, name, description) VALUES(?,?,?)" + , use(mAlias), use(mName), use(mDescription); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/Groups.h b/src/cpp/model/table/Groups.h index e69de29bb..adc5789c0 100644 --- a/src/cpp/model/table/Groups.h +++ b/src/cpp/model/table/Groups.h @@ -0,0 +1,35 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE + +#include "ModelBase.h" + +namespace model { + namespace table { + + class Groups : public ModelBase + { + public: + Groups(); + ~Groups(); + + // generic db operations + const char* getTableName() const { return "groups"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + std::string mAlias; + std::string mName; + std::string mDescription; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccounts.cpp b/src/cpp/model/table/HederaAccounts.cpp index e69de29bb..3c019374d 100644 --- a/src/cpp/model/table/HederaAccounts.cpp +++ b/src/cpp/model/table/HederaAccounts.cpp @@ -0,0 +1,63 @@ +#include "HederaAccounts.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + + HederaAccounts::HederaAccounts() + { + + } + + HederaAccounts::~HederaAccounts() + { + + } + + std::string HederaAccounts::toString() + { + std::stringstream ss; + ss << "user id: " << std::to_string(mUserId) << std::endl; + ss << "account hedera id: " << std::to_string(mAccountHederaId) << std::endl; + ss << "account crypto key id: " << std::to_string(mAccountKeyId) << std::endl; + // balance in tinybars, 100,000,000 tinybar = 1 HashBar + ss << "account balance: " << std::to_string((double)(mBalance) * 100000000.0) << " HBAR" << std::endl; + ss << "last update: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl; + + return ss.str(); + } + + Poco::Data::Statement HederaAccounts::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mUpdated); + + return select; + + } + Poco::Data::Statement HederaAccounts::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where account_hedera_id = ?" + , into(mID), use(mAccountHederaId); + unlock(); + return select; + } + Poco::Data::Statement HederaAccounts::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (user_id, account_hedera_id, account_key_id, balance) VALUES(?,?,?,?)" + , use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccounts.h b/src/cpp/model/table/HederaAccounts.h index e69de29bb..74b2063d4 100644 --- a/src/cpp/model/table/HederaAccounts.h +++ b/src/cpp/model/table/HederaAccounts.h @@ -0,0 +1,36 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE + +#include "ModelBase.h" + +namespace model { + namespace table { + + class HederaAccounts : public ModelBase + { + public: + HederaAccounts(); + ~HederaAccounts(); + + // generic db operations + const char* getTableName() const { return "hedera_accounts"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + int mUserId; + int mAccountHederaId; + int mAccountKeyId; + Poco::UInt64 mBalance; + Poco::DateTime mUpdated; + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaIds.cpp b/src/cpp/model/table/HederaIds.cpp index e69de29bb..8eeed0e55 100644 --- a/src/cpp/model/table/HederaIds.cpp +++ b/src/cpp/model/table/HederaIds.cpp @@ -0,0 +1,58 @@ +#include "HederaIds.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + HederaIds::HederaIds() + { + + } + + HederaIds::~HederaIds() + { + + } + + std::string HederaIds::toString() + { + std::stringstream ss; + ss << "Shard Num: " << std::to_string(mShardNum) << std::endl; + ss << "Realm Num: " << std::to_string(mRealmNum) << std::endl; + ss << "Num: " << std::to_string(mNum) << std::endl; + return ss.str(); + } + + Poco::Data::Statement HederaIds::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + + Poco::Data::Statement select(session); + + select << "SELECT id, shardNum, realmNum, num FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mShardNum), into(mRealmNum), into(mNum); + + return select; + } + Poco::Data::Statement HederaIds::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where shardNum = ? AND realmNum = ? AND num = ?" + , into(mID), use(mShardNum), use(mRealmNum), use(mNum); + unlock(); + return select; + } + Poco::Data::Statement HederaIds::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (shardNum, realmNum, num) VALUES(?,?,?)" + , use(mShardNum), use(mRealmNum), use(mNum); + unlock(); + return insert; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/HederaIds.h b/src/cpp/model/table/HederaIds.h index e69de29bb..eaa6612b8 100644 --- a/src/cpp/model/table/HederaIds.h +++ b/src/cpp/model/table/HederaIds.h @@ -0,0 +1,36 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE + +#include "ModelBase.h" +#include "Poco/Types.h" + +namespace model { + namespace table { + + class HederaIds : public ModelBase + { + public: + HederaIds(); + ~HederaIds(); + + // generic db operations + const char* getTableName() const { return "hedera_ids"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + Poco::UInt64 mShardNum; + Poco::UInt64 mRealmNum; + Poco::UInt64 mNum; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaTopics.cpp b/src/cpp/model/table/HederaTopics.cpp index e69de29bb..aeed1ea05 100644 --- a/src/cpp/model/table/HederaTopics.cpp +++ b/src/cpp/model/table/HederaTopics.cpp @@ -0,0 +1,69 @@ +#include "HederaTopics.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + HederaTopics::HederaTopics() + { + + } + + HederaTopics::~HederaTopics() + { + + } + + std::string HederaTopics::toString() + { + std::stringstream ss; + ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl; + ss << "Auto Renew Account Hedera id: " << std::to_string(mAutoRenewAccountHederaId) << std::endl; + ss << "Auto Renew Period: " << std::to_string(mAutoRenewPeriod) << " seconds" << std::endl; + ss << "Group id: " << std::to_string(mGroupId) << std::endl; + ss << "Admin Key id: " << std::to_string(mAdminKeyId) << std::endl; + ss << "Submit Key id: " << std::to_string(mSubmitKeyId) << std::endl; + ss << "Hedera Topic Tiemout: " << Poco::DateTimeFormatter::format(mCurrentTimeout, "%f.%m.%Y %H:%M:%S") << std::endl; + ss << "Hedera Topic Sequence Number: " << std::to_string(mSequenceNumber) << std::endl; + ss << "Updated: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl; + return ss.str(); + } + + Poco::Data::Statement HederaTopics::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period, " + << "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mTopicHederaId), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod) + , into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated); + + return select; + + } + Poco::Data::Statement HederaTopics::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where topic_hedera_id = ?" + , into(mID), use(mTopicHederaId); + unlock(); + return select; + } + Poco::Data::Statement HederaTopics::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period," + << " group_id, admin_key_id, submit_key_id, current_timeout, sequence_number) VALUES(?,?,?,?,?,?,?,?)" + , use(mTopicHederaId), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod) + , use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber), use(mUpdated); + unlock(); + return insert; + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/table/HederaTopics.h b/src/cpp/model/table/HederaTopics.h index e69de29bb..4584026ab 100644 --- a/src/cpp/model/table/HederaTopics.h +++ b/src/cpp/model/table/HederaTopics.h @@ -0,0 +1,41 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE + +#include "ModelBase.h" + +namespace model { + namespace table { + + class HederaTopics : public ModelBase + { + public: + HederaTopics(); + ~HederaTopics(); + + // generic db operations + const char* getTableName() const { return "hedera_topics"; } + std::string toString(); + + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + Poco::UInt32 mTopicHederaId; + Poco::UInt32 mAutoRenewAccountHederaId; + // in seconds + Poco::UInt32 mAutoRenewPeriod; + Poco::UInt32 mGroupId; + Poco::UInt32 mAdminKeyId; + Poco::UInt32 mSubmitKeyId; + Poco::DateTime mCurrentTimeout; + Poco::UInt64 mSequenceNumber; + Poco::DateTime mUpdated; + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE \ No newline at end of file From 03cce0071073a78b2e90c7de5c2278522543e396 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 25 Aug 2020 18:02:08 +0200 Subject: [PATCH 056/195] Rename table models to singular --- doc/.gitignore | 1 + .../HTTPInterface/AdminCheckUserBackup.cpp | 6 +- .../HTTPInterface/AdminUserPasswordReset.cpp | 8 +- .../HTTPInterface/RepairDefectPassphrase.cpp | 4 +- src/cpp/HTTPInterface/ResetPassword.cpp | 2 +- src/cpp/controller/User.cpp | 4 +- .../{UserBackups.cpp => UserBackup.cpp} | 28 +- .../{UserBackups.h => UserBackup.h} | 14 +- src/cpp/model/Session.cpp | 2646 ++++++++--------- src/cpp/model/User.cpp | 4 +- .../table/{CryptoKeys.cpp => CryptoKey.cpp} | 16 +- .../model/table/{CryptoKeys.h => CryptoKey.h} | 6 +- src/cpp/model/table/{Groups.cpp => Group.cpp} | 14 +- src/cpp/model/table/{Groups.h => Group.h} | 6 +- .../{HederaAccounts.cpp => HederaAccount.cpp} | 25 +- .../{HederaAccounts.h => HederaAccount.h} | 10 +- .../table/{HederaIds.cpp => HederaId.cpp} | 14 +- .../model/table/{HederaIds.h => HederaId.h} | 6 +- .../{HederaTopics.cpp => HederaTopic.cpp} | 14 +- .../table/{HederaTopics.h => HederaTopic.h} | 6 +- src/cpp/model/table/User.cpp | 4 +- src/cpp/model/table/User.h | 2 +- .../table/{UserBackups.cpp => UserBackup.cpp} | 24 +- .../table/{UserBackups.h => UserBackup.h} | 10 +- .../table/{UserRoles.cpp => UserRole.cpp} | 24 +- .../model/table/{UserRoles.h => UserRole.h} | 10 +- src/cpsp/adminCheckUserBackup.cpsp | 4 +- src/cpsp/adminUserPasswordReset.cpsp | 2 +- src/cpsp/repairDefectPassphrase.cpsp | 2 +- 29 files changed, 1466 insertions(+), 1450 deletions(-) create mode 100644 doc/.gitignore rename src/cpp/controller/{UserBackups.cpp => UserBackup.cpp} (70%) rename src/cpp/controller/{UserBackups.h => UserBackup.h} (68%) rename src/cpp/model/table/{CryptoKeys.cpp => CryptoKey.cpp} (75%) rename src/cpp/model/table/{CryptoKeys.h => CryptoKey.h} (92%) rename src/cpp/model/table/{Groups.cpp => Group.cpp} (73%) rename src/cpp/model/table/{Groups.h => Group.h} (91%) rename src/cpp/model/table/{HederaAccounts.cpp => HederaAccount.cpp} (66%) rename src/cpp/model/table/{HederaAccounts.h => HederaAccount.h} (72%) rename src/cpp/model/table/{HederaIds.cpp => HederaId.cpp} (74%) rename src/cpp/model/table/{HederaIds.h => HederaId.h} (91%) rename src/cpp/model/table/{HederaTopics.cpp => HederaTopic.cpp} (84%) rename src/cpp/model/table/{HederaTopics.h => HederaTopic.h} (92%) rename src/cpp/model/table/{UserBackups.cpp => UserBackup.cpp} (78%) rename src/cpp/model/table/{UserBackups.h => UserBackup.h} (88%) rename src/cpp/model/table/{UserRoles.cpp => UserRole.cpp} (73%) rename src/cpp/model/table/{UserRoles.h => UserRole.h} (90%) diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 000000000..1936cc1d4 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +html diff --git a/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp b/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp index 940d084bc..c2ebcd232 100644 --- a/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp +++ b/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp @@ -10,7 +10,7 @@ #include "../Crypto/KeyPair.h" #include "../SingletonManager/ConnectionManager.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "Poco/Data/Binding.h" using namespace Poco::Data::Keywords; @@ -20,7 +20,7 @@ typedef Poco::Tuple, std::string> UserBack struct SListEntry { Poco::AutoPtr user; - std::vector> backups; + std::vector> backups; }; #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" @@ -94,7 +94,7 @@ void AdminCheckUserBackup::handleRequest(Poco::Net::HTTPServerRequest& request, SListEntry entry; entry.user = controller::User::create(); entry.user->load(user_id); - entry.backups = controller::UserBackups::load(user_id); + entry.backups = controller::UserBackup::load(user_id); notMatchingEntrys.push_back(entry); diff --git a/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp index 42778fd45..71a2f1bb0 100644 --- a/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp +++ b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp @@ -10,7 +10,7 @@ // includes #include "../controller/User.h" #include "../controller/EmailVerificationCode.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" enum PageState @@ -43,7 +43,7 @@ void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request PageState state = PAGE_ASK_EMAIL; Poco::AutoPtr user = controller::User::create(); Poco::AutoPtr code; - Poco::AutoPtr userBackup; + Poco::AutoPtr userBackup; bool validUser = false; std::string pageName = "Admin User Passwort Reset"; @@ -69,7 +69,7 @@ void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request } } - auto backups = controller::UserBackups::load(userId); + auto backups = controller::UserBackup::load(userId); auto userPubkey = user->getModel()->getPublicKey(); for(auto it = backups.begin(); it != backups.end(); it++) { auto keys = (*it)->getKeyPair(); @@ -235,7 +235,7 @@ void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "Bitte schreibe sie dir auf und packe sie gut weg.\n"; responseStream << "\n"; #line 105 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" - responseStream << ( controller::UserBackups::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) ); + responseStream << ( controller::UserBackup::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) ); responseStream << "\n"; responseStream << " \n"; responseStream << "\n"; diff --git a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp index 3b8087c0c..77fd06514 100644 --- a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp +++ b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp @@ -13,7 +13,7 @@ #include "../Crypto/Passphrase.h" #include "../Crypto/KeyPairEd25519.h" #include "../lib/DataTypeConverter.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "../tasks/SigningTransaction.h" #include "../ServerConfig.h" @@ -85,7 +85,7 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request else { mSession->setPassphrase(passphrase); - auto newPassphraseModel = controller::UserBackups::create( + auto newPassphraseModel = controller::UserBackup::create( user_model->getID(), passphrase->getString(), ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES diff --git a/src/cpp/HTTPInterface/ResetPassword.cpp b/src/cpp/HTTPInterface/ResetPassword.cpp index 23d6b8331..7d1bbd28e 100644 --- a/src/cpp/HTTPInterface/ResetPassword.cpp +++ b/src/cpp/HTTPInterface/ResetPassword.cpp @@ -11,7 +11,7 @@ #include "../SingletonManager/SessionManager.h" #include "../SingletonManager/EmailManager.h" #include "../controller/User.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" enum PageState { PAGE_EMAIL_ASK, diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 32a3ab700..fc94661fb 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -1,5 +1,5 @@ #include "User.h" -#include "UserBackups.h" +#include "UserBackup.h" #include "sodium.h" @@ -299,7 +299,7 @@ namespace controller { auto user_model = getModel(); if (user_model->getID() <= 0) return -2; - auto backups = UserBackups::load(user_model->getID()); + auto backups = UserBackup::load(user_model->getID()); if (backups.size() == 0) return -1; for (auto it = backups.begin(); it != backups.end(); it++) { auto user_backup = *it; diff --git a/src/cpp/controller/UserBackups.cpp b/src/cpp/controller/UserBackup.cpp similarity index 70% rename from src/cpp/controller/UserBackups.cpp rename to src/cpp/controller/UserBackup.cpp index bf7096442..9a152592f 100644 --- a/src/cpp/controller/UserBackups.cpp +++ b/src/cpp/controller/UserBackup.cpp @@ -1,14 +1,14 @@ -#include "UserBackups.h" +#include "UserBackup.h" #include "../Crypto/Passphrase.h" namespace controller { - UserBackups::UserBackups(model::table::UserBackups* dbModel) + UserBackup::UserBackup(model::table::UserBackup* dbModel) { mDBModel = dbModel; } - UserBackups::~UserBackups() + UserBackup::~UserBackup() { } @@ -17,20 +17,20 @@ namespace controller { // --------------- static members ----------------------------- - Poco::AutoPtr UserBackups::create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) + Poco::AutoPtr UserBackup::create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) { - auto db = new model::table::UserBackups(user_id, passphrase, type); - return Poco::AutoPtr(new UserBackups(db)); + auto db = new model::table::UserBackup(user_id, passphrase, type); + return Poco::AutoPtr(new UserBackup(db)); } - std::vector> UserBackups::load(int user_id) + std::vector> UserBackup::load(int user_id) { - auto db = new model::table::UserBackups(); + auto db = new model::table::UserBackup(); auto results = db->loadFromDB("user_id", user_id, 1); - std::vector> resultObjects; + std::vector> resultObjects; if (db->errorCount()) { db->sendErrorsAsEmail(); db->release(); @@ -41,14 +41,14 @@ namespace controller { return resultObjects; } for (auto it = results.begin(); it != results.end(); it++) { - resultObjects.push_back(new UserBackups(new model::table::UserBackups(*it))); + resultObjects.push_back(new UserBackup(new model::table::UserBackup(*it))); } return resultObjects; } - Poco::SharedPtr UserBackups::getKeyPair() + Poco::SharedPtr UserBackup::getKeyPair() { if (!mKeyPair.isNull()) { return mKeyPair; @@ -61,7 +61,7 @@ namespace controller { return mKeyPair; } - KeyPairEd25519* UserBackups::createGradidoKeyPair() + KeyPairEd25519* UserBackup::createGradidoKeyPair() { auto model = getModel(); auto mnemonicType = model->getMnemonicType(); @@ -71,7 +71,7 @@ namespace controller { return KeyPairEd25519::create(passphrase); } - std::string UserBackups::getPassphrase(ServerConfig::Mnemonic_Types type) + std::string UserBackup::getPassphrase(ServerConfig::Mnemonic_Types type) { if ((int)type < 0 || (int)type >= ServerConfig::Mnemonic_Types::MNEMONIC_MAX) { return ""; @@ -96,7 +96,7 @@ namespace controller { } - std::string UserBackups::formatPassphrase(std::string passphrase, int targetLinesCount/* = 5*/) + std::string UserBackup::formatPassphrase(std::string passphrase, int targetLinesCount/* = 5*/) { int count = passphrase.size(); int charPerLine = count / (targetLinesCount); diff --git a/src/cpp/controller/UserBackups.h b/src/cpp/controller/UserBackup.h similarity index 68% rename from src/cpp/controller/UserBackups.h rename to src/cpp/controller/UserBackup.h index c1cb08047..a21d1c3ab 100644 --- a/src/cpp/controller/UserBackups.h +++ b/src/cpp/controller/UserBackup.h @@ -1,7 +1,7 @@ #ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE #define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE -#include "../model/table/UserBackups.h" +#include "../model/table/UserBackup.h" #include "../Crypto/KeyPair.h" #include "../Crypto/KeyPairEd25519.h" @@ -10,19 +10,19 @@ #include "TableControllerBase.h" namespace controller { - class UserBackups : public TableControllerBase + class UserBackup : public TableControllerBase { public: - ~UserBackups(); + ~UserBackup(); - static Poco::AutoPtr create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); + static Poco::AutoPtr create(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); - static std::vector> load(int user_id); + static std::vector> load(int user_id); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } - inline Poco::AutoPtr getModel() { return _getModel(); } + inline Poco::AutoPtr getModel() { return _getModel(); } //! depracted //! \return create keyPair from passphrase if not exist, else return existing pointer @@ -37,7 +37,7 @@ namespace controller { std::string getPassphrase(ServerConfig::Mnemonic_Types type); protected: - UserBackups(model::table::UserBackups* dbModel); + UserBackup(model::table::UserBackup* dbModel); Poco::SharedPtr mKeyPair; }; diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 86fad389c..783fdc2e8 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -1,1323 +1,1323 @@ -#include "Session.h" -#include "../lib/Profiler.h" -#include "../ServerConfig.h" - -#include "Poco/RegularExpression.h" -#include "Poco/Net/StringPartSource.h" -#include "Poco/Net/MediaType.h" - -#include "../SingletonManager/SessionManager.h" -#include "../SingletonManager/ConnectionManager.h" -#include "../SingletonManager/ErrorManager.h" -#include "../SingletonManager/EmailManager.h" -#include "../SingletonManager/SingletonTaskObserver.h" - -#include "../tasks/PrepareEmailTask.h" -#include "../tasks/SendEmailTask.h" -#include "../tasks/SigningTransaction.h" -#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h" -#include "../tasks/VerificationEmailResendTask.h" - -#include "../lib/JsonRequest.h" - -#include "../Crypto/Passphrase.h" - - -#include "../controller/User.h" -#include "../controller/UserBackups.h" -#include "../controller/EmailVerificationCode.h" - -#include "table/ModelBase.h" - - -#include "sodium.h" - -using namespace Poco::Data::Keywords; - -int WriteEmailVerification::run() -{ - auto em = ErrorManager::getInstance(); - - mEmailVerificationCode->getModel()->setUserId(mUser->getDBId()); - auto emailVerificationModel = mEmailVerificationCode->getModel(); - emailVerificationModel->setUserId(mUser->getDBId()); - if (!emailVerificationModel->insertIntoDB(true) || emailVerificationModel->errorCount() > 0) { - emailVerificationModel->sendErrorsAsEmail(); - return -1; - } - - return 0; -} - -// --------------------------------------------------------------------------------------------------------------- - -int WritePassphraseIntoDB::run() -{ - Profiler timeUsed; - - // TODO: encrypt passphrase, need server admin crypto box pubkey - //int crypto_box_seal(unsigned char *c, const unsigned char *m, - //unsigned long long mlen, const unsigned char *pk); - size_t mlen = mPassphrase.size(); - size_t crypto_size = crypto_box_SEALBYTES + mlen; - - auto em = ErrorManager::getInstance(); - - auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement insert(dbSession); - insert << "INSERT INTO user_backups (user_id, passphrase) VALUES(?,?)", - use(mUserId), use(mPassphrase); - try { - if (insert.execute() != 1) { - em->addError(new ParamError("WritePassphraseIntoDB::run", "inserting passphrase for user failed", std::to_string(mUserId))); - em->sendErrorsAsEmail(); - } - } - catch (Poco::Exception& ex) { - em->addError(new ParamError("WritePassphraseIntoDB::run", "insert passphrase mysql error", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - - //printf("[WritePassphraseIntoDB] timeUsed: %s\n", timeUsed.string().data()); - return 0; -} - - -// -------------------------------------------------------------------------------------------------------------- - -Session::Session(int handle) - : mHandleId(handle), mSessionUser(nullptr), mState(SESSION_STATE_EMPTY), mActive(false) -{ - -} - -Session::~Session() -{ - //printf("[Session::~Session] \n"); - if (tryLock()) { - unlock(); - reset(); - } - - - //printf("[Session::~Session] finished \n"); -} - - -void Session::reset() -{ - //printf("[Session::reset]\n"); - lock("Session::reset"); - std::unique_lock _lock(mSharedMutex); - mSessionUser.assign(nullptr); - mNewUser.assign(nullptr); - mEmailVerificationCodeObject.assign(nullptr); - - // watch out - //updateTimeout(); - mLastActivity = Poco::DateTime(); - - mState = SESSION_STATE_EMPTY; - - mPassphrase = ""; - mLastExternReferer = ""; - mClientLoginIP = Poco::Net::IPAddress(); - unlock(); - - // reset transactions - mCurrentActiveProcessingTransaction = nullptr; - mProcessingTransactions.clear(); - - //printf("[Session::reset] finished\n"); -} - -int Session::isActive() -{ - int ret = 0; - try { - mWorkMutex.tryLock(100); - } - catch (Poco::TimeoutException &ex) { - return -1; - } - ret = (int)mActive; - unlock(); - return ret; - -} - -bool Session::isDeadLocked() -{ - try { - mWorkMutex.tryLock(200); - unlock(); - return false; - } - catch (Poco::Exception& ex) { - - } - return true; -} - -bool Session::setActive(bool active) -{ - try { - mWorkMutex.tryLock(100); - } - catch (Poco::TimeoutException &ex) { - return false; - } - mActive = active; - unlock(); - return true; -} - -void Session::updateTimeout() -{ - lock("Session::updateTimeout"); - mLastActivity = Poco::DateTime(); - unlock(); -} - -Poco::AutoPtr Session::getEmailVerificationCodeObject() -{ - lock("Session::getEmailVerificationCodeObject"); - std::shared_lock _lock(mSharedMutex); - auto ret = mEmailVerificationCodeObject; - unlock(); - return ret; -} - -bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email) -{ - Profiler usedTime; - - if (mNewUser->getModel()->getRole() != model::table::ROLE_ADMIN) { - addError(new Error(gettext("Benutzer"), gettext("Eingeloggter Benutzer ist kein Admin")), false); - return false; - } - - auto sm = SessionManager::getInstance(); - if (!sm->isValid(first_name, VALIDATE_NAME)) { - addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(last_name, VALIDATE_NAME)) { - addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(email, VALIDATE_EMAIL)) { - addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); - return false; - } - - - // check if user with that email already exist - if (mNewUser->getModel()->isExistInDB("email", email)) { - addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits einen Account")), false); - return false; - } - - auto newUser = controller::User::create(email, first_name, last_name); - updateTimeout(); - - - auto newUserModel = newUser->getModel(); - if (!newUserModel->insertIntoDB(true)) { - addError(new Error(gettext("Benutzer"), gettext("Fehler beim speichern!"))); - return false; - } - - auto email_verification_code = controller::EmailVerificationCode::create(newUserModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); - if (!email_verification_code->getModel()->insertIntoDB(false)) { - addError(new Error(gettext("Email Verification Code"), gettext("Fehler beim speichern!"))); - return false; - } - - EmailManager::getInstance()->addEmail(new model::Email(email_verification_code, newUser, model::EMAIL_ADMIN_USER_VERIFICATION_CODE)); - - std::unique_lock _lock(mSharedMutex); - mEmailVerificationCodeObject = email_verification_code; - - - return true; -} -// -bool Session::createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) -{ - Profiler usedTime; - auto sm = SessionManager::getInstance(); - if (!sm->isValid(first_name, VALIDATE_NAME)) { - addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(last_name, VALIDATE_NAME)) { - addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(email, VALIDATE_EMAIL)) { - addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); - return false; - } - if (!sm->checkPwdValidation(password, this)) { - return false; - } - /*if (passphrase.size() > 0 && !sm->isValid(passphrase, VALIDATE_PASSPHRASE)) { - addError(new Error("Merkspruch", "Der Merkspruch ist nicht gültig, er besteht aus 24 Wörtern, mit Komma getrennt.")); - return false; - } - if (passphrase.size() == 0) { - //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - } - else { - //mPassphrase = passphrase; - }*/ - - // check if user with that email already exist - - auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement select(dbConnection); - select << "SELECT email from users where email = ?;", useRef(email); - try { - if (select.execute() > 0) { - addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits einen Account")), false); - return false; - } - } - catch (Poco::Exception& exc) { - printf("mysql exception: %s\n", exc.displayText().data()); - } - - mSessionUser = new User(email.data(), first_name.data(), last_name.data()); - mNewUser = controller::User::create(email, first_name, last_name); - updateTimeout(); - - // Prepare E-Mail - //UniLib::controller::TaskPtr prepareEmail(new PrepareEmailTask(ServerConfig::g_CPUScheduler)); - //prepareEmail->scheduleTask(prepareEmail); - - // create user crypto key - UniLib::controller::TaskPtr cryptoKeyTask(new UserCreateCryptoKey(mSessionUser, mNewUser, password, ServerConfig::g_CryptoCPUScheduler)); - cryptoKeyTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_CRYPTO_KEY_GENERATED, this)); - cryptoKeyTask->scheduleTask(cryptoKeyTask); - - // depends on crypto key, write user record into db - UniLib::controller::TaskPtr writeUserIntoDB(new UserWriteIntoDB(mSessionUser, ServerConfig::g_CPUScheduler, 1)); - writeUserIntoDB->setParentTaskPtrInArray(cryptoKeyTask, 0); - writeUserIntoDB->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_USER_WRITTEN, this)); - writeUserIntoDB->scheduleTask(writeUserIntoDB); - - std::unique_lock _lock(mSharedMutex); - mEmailVerificationCodeObject = controller::EmailVerificationCode::create(model::table::EMAIL_OPT_IN_REGISTER); - UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, mEmailVerificationCodeObject, ServerConfig::g_CPUScheduler, 1)); - - writeEmailVerification->setParentTaskPtrInArray(writeUserIntoDB, 0); - writeEmailVerification->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, this)); - writeEmailVerification->scheduleTask(writeEmailVerification); - - - /*printf("LastName: %s\n", last_name.data()); - for (int i = 0; i < last_name.size(); i++) { - char c = last_name.data()[i]; - //printf("%d ", c); - } - //printf("\n\n"); - */ - - // depends on writeUser because need user_id, write email verification into db - /*auto message = new Poco::Net::MailMessage; - Poco::Net::MediaType mt("text", "plain"); - mt.setParameter("charset", "utf-8"); - message->setContentType(mt); - - message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, email)); - message->setSubject(gettext("Gradido: E-Mail Verification")); - std::stringstream ss; - ss << "Hallo " << first_name << " " << last_name << "," << std::endl << std::endl; - ss << "Du oder jemand anderes hat sich soeben mit dieser E-Mail Adresse bei Gradido registriert. " << std::endl; - ss << "Wenn du es warst, klicke bitte auf den Link: " << ServerConfig::g_serverPath << "/checkEmail/" << mEmailVerificationCode << std::endl; - //ss << "oder kopiere den Code: " << mEmailVerificationCode << " selbst dort hinein." << std::endl; - ss << "oder kopiere den obigen Link in Dein Browserfenster." << std::endl; - ss << std::endl; - ss << "Mit freundlichen " << u8"Grüßen" << std::endl; - ss << "Dario, Gradido Server Admin" << std::endl; - - - message->addContent(new Poco::Net::StringPartSource(ss.str())); - */ - //UniLib::controller::TaskPtr sendEmail(new SendEmailTask(message, ServerConfig::g_CPUScheduler, 1)); - //Email(AutoPtr emailVerification, AutoPtr user, EmailType type); - UniLib::controller::TaskPtr sendEmail(new SendEmailTask(new model::Email(mEmailVerificationCodeObject, mNewUser, model::EMAIL_USER_VERIFICATION_CODE), ServerConfig::g_CPUScheduler, 1)); - //sendEmail->setParentTaskPtrInArray(prepareEmail, 0); - sendEmail->setParentTaskPtrInArray(writeEmailVerification, 0); - sendEmail->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_SEND, this)); - sendEmail->scheduleTask(sendEmail); - - // write user into db - // generate and write email verification into db - // send email - - //printf("[Session::createUser] time: %s\n", usedTime.string().data()); - - return true; -} - -bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) -{ - std::unique_lock _lock(mSharedMutex); - static const char* function_name = "Session::createUserDirect"; - auto sm = SessionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto email_manager = EmailManager::getInstance(); - - if (!sm->isValid(first_name, VALIDATE_NAME)) { - addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(last_name, VALIDATE_NAME)) { - addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); - return false; - } - if (!sm->isValid(email, VALIDATE_EMAIL)) { - addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); - return false; - } - if (!sm->checkPwdValidation(password, this)) { - return false; - } - - // check if email already exist - auto user = controller::User::create(); - if (user->load(email) >= 1) { - addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits ein Konto")), false); - return false; - } - - // user - mNewUser = controller::User::create(email, first_name, last_name); - auto user_model = mNewUser->getModel(); - user_model->insertIntoDB(true); - auto user_id = user_model->getID(); - - - // one retry in case of connection error - if (!user_id) { - user_model->insertIntoDB(true); - auto user_id = user_model->getID(); - if (!user_id) { - em->addError(new ParamError(function_name, "error saving new user in db, after one retry with email", email)); - em->sendErrorsAsEmail(); - addError(new Error(gettext("Server"), gettext("Fehler beim speichen des Kontos bitte versuche es später noch einmal")), false); - return false; - } - } - - generateKeys(true, true); - - // calculate encryption key, could need some time, will save encrypted privkey to db - UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(mNewUser, password); - create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); - - // email verification code - auto email_verification = controller::EmailVerificationCode::create(user_id, model::table::EMAIL_OPT_IN_REGISTER_DIRECT); - email_verification->getModel()->insertIntoDB(false); - mEmailVerificationCodeObject = email_verification; - - auto _7days_later = Poco::DateTime() + Poco::Timespan(7, 0, 0, 0, 0); - ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(_7days_later.timestamp())); - - email_manager->addEmail(new model::Email(email_verification, mNewUser, model::EMAIL_USER_VERIFICATION_CODE)); - - return true; -} - -bool Session::ifUserExist(const std::string& email) -{ - auto em = ErrorManager::getInstance(); - const char* funcName = "Session::ifUserExist"; - auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement select(dbConnection); - bool emailChecked = false; - int userId = 0; - select << "SELECT email_checked, id from users where email = ? and email_checked = 1", - into(emailChecked), into(userId), useRef(email); - - try { - if(select.execute() == 1) return true; - } - catch (Poco::Exception& ex) { - em->addError(new ParamError(funcName, "select user from email verification code mysql error ", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - return false; -} - -int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) -{ - const static char* funcName = "Session::updateEmailVerification"; - Poco::ScopedLock _lock(mWorkMutex); - // new mutex, will replace the Poco Mutex complete in the future - std::unique_lock _lock_shared(mSharedMutex); - Profiler usedTime; - - auto em = ErrorManager::getInstance(); - if (mEmailVerificationCodeObject.isNull()) { - em->addError(new Error(funcName, "email verification object is zero")); - em->sendErrorsAsEmail(); - - return -2; - } - auto email_verification_code_model = mEmailVerificationCodeObject->getModel(); - assert(email_verification_code_model); - if(email_verification_code_model->getCode() == emailVerificationCode) { - if (mSessionUser && mSessionUser->getDBId() == 0) { - //addError(new Error("E-Mail Verification", "Benutzer wurde nicht richtig gespeichert, bitte wende dich an den Server-Admin")); - em->addError(new Error(funcName, "user exist with 0 as id")); - em->sendErrorsAsEmail(); - - //return false; - return -2; - } - - // load correct user from db - if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getModel()->getID() != email_verification_code_model->getUserId()) { - mNewUser = controller::User::create(); - if (1 != mNewUser->load(email_verification_code_model->getUserId())) { - em->addError(new ParamError(funcName, "user load didn't return 1 with user_id ", email_verification_code_model->getUserId())); - em->sendErrorsAsEmail(); - - return -2; - } - } - - auto user_model = mNewUser->getModel(); - assert(user_model); - bool first_email_activation = false; - auto verification_type = email_verification_code_model->getType(); - if (model::table::EMAIL_OPT_IN_REGISTER == verification_type || - model::table::EMAIL_OPT_IN_EMPTY == verification_type || - model::table::EMAIL_OPT_IN_REGISTER_DIRECT == verification_type) { - first_email_activation = true; - } - if (first_email_activation && user_model->isEmailChecked()) { - mSessionUser = new User(mNewUser); - addError(new Error(gettext("E-Mail Verification"), gettext("Du hast dein Konto bereits aktiviert!")), false); - - return 1; - } - if (first_email_activation) { - user_model->setEmailChecked(true); - - user_model->updateIntoDB("email_checked", 1); - if (user_model->errorCount() > 0) { - user_model->sendErrorsAsEmail(); - } - - // no find all active sessions - - updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); - return 0; - } - - if (email_verification_code_model->getType() == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { - - if (mEmailVerificationCodeObject->deleteFromDB()) { - mEmailVerificationCodeObject.assign(nullptr); - } - else { - em->getErrors(mEmailVerificationCodeObject->getModel()); - em->addError(new Error(funcName, "error deleting email verification code")); - em->sendErrorsAsEmail(); - return -2; - } - updateState(SESSION_STATE_RESET_PASSWORD_REQUEST); - return 0; - } - - em->addError(new Error(funcName, "invalid code path")); - em->sendErrorsAsEmail(); - - return -2; - - /*if (updated_rows == 1) { - Poco::Data::Statement delete_row(dbConnection); - delete_row << "DELETE FROM email_opt_in where verification_code = ?", use(emailVerificationCode); - if (delete_row.execute() != 1) { - em->addError(new Error(funcName, "delete from email_opt_in entry didn't work as expected, please check db")); - em->sendErrorsAsEmail(); - } - if (mSessionUser) { - mSessionUser->setEmailChecked(); - mSessionUser->setLanguage(getLanguage()); - } - updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); - //printf("[%s] time: %s\n", funcName, usedTime.string().data()); - unlock(); - return true; - } - else { - em->addError(new ParamError(funcName, "update user work not like expected, updated row count", updated_rows)); - em->sendErrorsAsEmail(); - }*/ - - - } - else { - addError(new Error(gettext("E-Mail Verification"), gettext("Falscher Code für aktiven Login"))); - //printf("[%s] time: %s\n", funcName, usedTime.string().data()); - - return -1; - } - //printf("[%s] time: %s\n", funcName, usedTime.string().data()); - - return 0; -} - - -int Session::sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized) -{ - mNewUser = user; - mSessionUser = new User(user); - auto em = EmailManager::getInstance(); - - std::unique_lock _lock(mSharedMutex); - - // creating email verification code also for user without passphrase - // first check if already exist - // check if email was already send shortly before - bool frequent_resend = false; - bool email_already_send = false; - - mEmailVerificationCodeObject = controller::EmailVerificationCode::load(user->getModel()->getID(), model::table::EMAIL_OPT_IN_RESET_PASSWORD); - if (mEmailVerificationCodeObject.isNull()) { - mEmailVerificationCodeObject = controller::EmailVerificationCode::create(mNewUser->getModel()->getID(), model::table::EMAIL_OPT_IN_RESET_PASSWORD); - mEmailVerificationCodeObject->getModel()->insertIntoDB(false); - } - else { - email_already_send = true; - } - auto email_verification_model = mEmailVerificationCodeObject->getModel(); - if (email_already_send) { - auto time_elapsed = Poco::DateTime() - email_verification_model->getUpdated(); - if (time_elapsed.totalHours() < 1) { - frequent_resend = true; - } - } - - if (!frequent_resend) { - if (passphraseMemorized) { - em->addEmail(new model::Email(mEmailVerificationCodeObject, mNewUser, model::EMAIL_USER_RESET_PASSWORD)); - } - else { - em->addEmail(new model::Email(user, model::EMAIL_ADMIN_RESET_PASSWORD_REQUEST_WITHOUT_MEMORIZED_PASSPHRASE)); - } - } - - if (frequent_resend) return 2; - if (email_already_send) return 1; - - return 0; -} - -int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource) -{ - KeyPair keys; - static const char* functionName = "Session::comparePassphraseWithSavedKeys"; - if (!wordSource) { - addError(new Error(functionName, "wordSource is empty")); - sendErrorsAsEmail(); - return -2; - } - if (!keys.generateFromPassphrase(inputPassphrase.data(), wordSource)) { - addError(new ParamError(functionName, "invalid passphrase", inputPassphrase)); - if (!mNewUser.isNull() && mNewUser->getModel()) { - addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); - } - sendErrorsAsEmail(); - addError(new Error(gettext("Passphrase"), gettext("Deine Passphrase ist ungütig")), false); - return 0; - } - auto userModel = mNewUser->getModel(); - auto existingPublic = userModel->getPublicKey(); - if (!existingPublic) { - userModel->loadFromDB("email", userModel->getEmail()); - existingPublic = userModel->getPublicKey(); - if (!existingPublic) { - addError(new Error(functionName, "cannot load existing public key from db")); - addError(new ParamError(functionName, "user email", userModel->getEmail())); - sendErrorsAsEmail(); - addError(new Error(gettext("Passphrase"), gettext("Ein Fehler trat auf, bitte versuche es erneut")), false); - return -1; - } - } - if (0 == memcmp(userModel->getPublicKey(), keys.getPublicKey(), crypto_sign_PUBLICKEYBYTES)) { - mPassphrase = inputPassphrase; - return 1; - } - addError(new Error(gettext("Passphrase"), gettext("Das ist nicht die richtige Passphrase.")), false); - return 0; -} - -bool Session::startProcessingTransaction(const std::string& proto_message_base64, bool autoSign/* = false*/) -{ - static const char* funcName = "Session::startProcessingTransaction"; - lock(funcName); - HASH hs = ProcessingTransaction::calculateHash(proto_message_base64); - // check if it is already running or waiting - for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { - if (it->isNull()) { - it = mProcessingTransactions.erase(it); - } - if (hs == (*it)->getHash()) { - addError(new Error(funcName, "transaction already in list")); - unlock(); - return false; - } - } - if (mSessionUser.isNull() || !mSessionUser->getEmail()) { - addError(new Error(funcName, "user is zero")); - unlock(); - return false; - } - - Poco::AutoPtr processorTask( - new ProcessingTransaction( - proto_message_base64, - DRMakeStringHash(mSessionUser->getEmail()), - mSessionUser->getLanguage()) - ); - if (autoSign && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) == ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) { - if (processorTask->run() != 0) { - getErrors(processorTask); - unlock(); - return false; - } - Poco::AutoPtr signingTransaction(new SigningTransaction(processorTask, mNewUser)); - //signingTransaction->scheduleTask(signingTransaction); - if (signingTransaction->run() != 0) { - getErrors(signingTransaction); - unlock(); - return false; - } - - } - else { - processorTask->scheduleTask(processorTask); - mProcessingTransactions.push_back(processorTask); - } - unlock(); - return true; - -} - -Poco::AutoPtr Session::getNextReadyTransaction(size_t* working/* = nullptr*/) -{ - lock("Session::getNextReadyTransaction"); - if (working) { - *working = 0; - } - else if (!mCurrentActiveProcessingTransaction.isNull()) - { - unlock(); - return mCurrentActiveProcessingTransaction; - } - for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { - if (working && !(*it)->isTaskFinished()) { - (*working)++; - } - if (mCurrentActiveProcessingTransaction.isNull() && (*it)->isTaskFinished()) { - if (!working) { - mCurrentActiveProcessingTransaction = *it; - unlock(); - return mCurrentActiveProcessingTransaction; - } - // no early exit - else { - mCurrentActiveProcessingTransaction = *it; - } - - } - } - unlock(); - return mCurrentActiveProcessingTransaction; -} - -bool Session::finalizeTransaction(bool sign, bool reject) -{ - int result = -1; - lock("Session::finalizeTransaction"); - if (mCurrentActiveProcessingTransaction.isNull()) { - unlock(); - return false; - } - mProcessingTransactions.remove(mCurrentActiveProcessingTransaction); - - if (!reject) { - if (sign) { - Poco::AutoPtr signingTransaction(new SigningTransaction(mCurrentActiveProcessingTransaction, mNewUser)); - //signingTransaction->scheduleTask(signingTransaction); - result = signingTransaction->run(); - } - } - mCurrentActiveProcessingTransaction.assign(nullptr); - unlock(); - return result == 0; -} - -size_t Session::getProcessingTransactionCount() -{ - size_t count = 0; - lock("Session::getProcessingTransactionCount"); - - for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { - - (*it)->lock(); - if ((*it)->errorCount() > 0) { - (*it)->sendErrorsAsEmail(); - (*it)->unlock(); - it = mProcessingTransactions.erase(it); - if (it == mProcessingTransactions.end()) break; - } - else { - (*it)->unlock(); - } - - } - count = mProcessingTransactions.size(); - unlock(); - return count; -} - -bool Session::isPwdValid(const std::string& pwd) -{ - if (mSessionUser) { - return mSessionUser->validatePwd(pwd, this); - } - return false; -} - -UserStates Session::loadUser(const std::string& email, const std::string& password) -{ - static const char* functionName = "Session::loadUser"; - auto observer = SingletonTaskObserver::getInstance(); - if (email != "") { - if (observer->getTaskCount(email, TASK_OBSERVER_PASSWORD_CREATION) > 0) { - return USER_PASSWORD_ENCRYPTION_IN_PROCESS; - } - } - //Profiler usedTime; - //printf("before lock\n"); - lock(functionName); - //printf("locked \n"); - if (!mSessionUser.isNull() && mSessionUser->getEmail() != email) { - mSessionUser.assign(nullptr); - mNewUser.assign(nullptr); - //printf("user nullptr assigned\n"); - } - //printf("after checking if session user is null\n"); - //if (!mSessionUser) { - if (mNewUser.isNull()) { - //printf("new user is null\n"); - mNewUser = controller::User::create(); - //printf("new user created\n"); - // load user for email only once from db - mNewUser->load(email); - //printf("load new user from db with email: %s\n", email.data()); - mSessionUser = new User(mNewUser); - //mSessionUser = new User(email.data()); - - //printf("user loaded from email\n"); - } - //printf("before get model\n"); - auto user_model = mNewUser->getModel(); - if (user_model && user_model->isDisabled()) { - return USER_DISABLED; - } - //printf("before if login\n"); - if (!mSessionUser.isNull() && mSessionUser->getUserState() >= USER_LOADED_FROM_DB) { - //printf("before login\n"); - int loginResult = 0; - int exitCount = 0; - do { - loginResult = mNewUser->login(password); - Poco::Thread::sleep(100); - exitCount++; - } while (-3 == loginResult && exitCount < 15); - if (exitCount > 1) { - addError(new ParamError(functionName, "login succeed, retrys: ", exitCount)); - addError(new ParamError(functionName, "email: ", email)); - sendErrorsAsEmail(); - } - - if (exitCount >= 15) - { - auto running_password_creations = observer->getTasksCount(TASK_OBSERVER_PASSWORD_CREATION); - - addError(new ParamError(functionName, "login failed after 15 retrys and 100 ms sleep between, currently running passwort creation tasks: ", running_password_creations)); - addError(new ParamError(functionName, "email: ", email)); - sendErrorsAsEmail(); - return USER_PASSWORD_ENCRYPTION_IN_PROCESS; - } - - //printf("new user login with result: %d\n", loginResult); - - if (-1 == loginResult) { - addError(new Error(functionName, "error in user data set, saved pubkey didn't match extracted pubkey from private key")); - addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); - sendErrorsAsEmail(); - //unlock(); - //return USER_KEYS_DONT_MATCH; - } - if (0 == loginResult) { - unlock(); - return USER_PASSWORD_INCORRECT; - } - // error decrypting private key - if (-2 == loginResult) { - // check if we have access to the passphrase, if so we can reencrypt the private key - printf("try reencrypting key\n"); - auto user_model = mNewUser->getModel(); - auto user_backups = controller::UserBackups::load(user_model->getID()); - for (auto it = user_backups.begin(); it != user_backups.end(); it++) { - auto key = std::unique_ptr((*it)->createGradidoKeyPair()); - if (key->isTheSame(user_model->getPublicKey())) - { - - // set valid key pair - if (1 == mNewUser->setGradidoKeyPair(key.release())) { - // save new encrypted private key - user_model->updatePrivkey(); - } - else { - auto em = ErrorManager::getInstance(); - em->addError(new Error(functionName, "error reencrypt private key")); - em->addError(new ParamError(functionName, "for user with email", user_model->getEmail())); - em->sendErrorsAsEmail(); - } - break; - } - } - } - // can be removed if session user isn't used any more - // don't calculate password two times anymore - mSessionUser->login(mNewUser); - //printf("after old user login\n"); - /*if (mNewUser->getModel()->getPasswordHashed() && !mSessionUser->validatePwd(password, this)) { - unlock(); - return USER_PASSWORD_INCORRECT; - }*/ - } - else { - //printf("before sleep\n"); - User::fakeCreateCryptoKey(); - } - - /*if (!mSessionUser->validatePwd(password, this)) { - addError(new Error("Login", "E-Mail oder Passwort nicht korrekt, bitte versuche es erneut!")); - unlock(); - return false; - } - if (!mSessionUser->isEmailChecked()) { - addError(new Error("Account", "E-Mail Adresse wurde noch nicht bestätigt, hast du schon eine E-Mail erhalten?")); - unlock(); - return false; - }*/ - //printf("before detect session state\n"); - detectSessionState(); - unlock(); - //printf("before return user state\n"); - return mSessionUser->getUserState(); -} - -bool Session::deleteUser() -{ - lock("Session::deleteUser"); - bool bResult = false; - if(mSessionUser) { - JsonRequest phpServerRequest(ServerConfig::g_php_serverHost, 443); - Poco::Net::NameValueCollection payload; - payload.add("user", std::string(mSessionUser->getPublicKeyHex())); - //auto ret = phpServerRequest.request("userDelete", payload); - JsonRequestReturn ret = JSON_REQUEST_RETURN_OK; - if (ret == JSON_REQUEST_RETURN_ERROR) { - addError(new Error("Session::deleteUser", "php server error")); - getErrors(&phpServerRequest); - sendErrorsAsEmail(); - } - else if (ret == JSON_REQUEST_RETURN_OK) { - bResult = mSessionUser->deleteFromDB(); - } - else { - addError(new Error(gettext("Benutzer"), gettext("Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."))); - unlock(); - return false; - } - } - if(!bResult) { - addError(new Error(gettext("Benutzer"), gettext("Fehler beim Löschen des Accounts. Bitte logge dich erneut ein und versuche es nochmal."))); - } - unlock(); - return bResult; -} - -void Session::setLanguage(Languages lang) -{ - //printf("[Session::setLanguage] new language: %d\n", lang); - lock("Session::setLanguage"); - if (mLanguageCatalog.isNull() || mLanguageCatalog->getLanguage() != lang) { - auto lm = LanguageManager::getInstance(); - mLanguageCatalog = lm->getFreeCatalog(lang); - } - unlock(); -} - -Languages Session::getLanguage() -{ - Languages lang = LANG_NULL; - lock("Session::getLanguage"); - if (!mLanguageCatalog.isNull()) { - lang = mLanguageCatalog->getLanguage(); - } - unlock(); - return lang; -} - - -/* -SESSION_STATE_CRYPTO_KEY_GENERATED, -SESSION_STATE_USER_WRITTEN, -SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, -SESSION_STATE_EMAIL_VERIFICATION_SEND, -SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED, -SESSION_STATE_PASSPHRASE_GENERATED, -SESSION_STATE_PASSPHRASE_SHOWN, -SESSION_STATE_PASSPHRASE_WRITTEN, -SESSION_STATE_KEY_PAIR_GENERATED, -SESSION_STATE_KEY_PAIR_WRITTEN, -SESSION_STATE_COUNT -*/ -void Session::detectSessionState() -{ - if (mSessionUser.isNull() || !mSessionUser->hasCryptoKey()) { - return; - } - UserStates userState = mSessionUser->getUserState(); - - int checkEmail = -1, resetPasswd = -1; - try { - auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mSessionUser->getDBId()); - - for (int i = 0; i < emailVerificationCodeObjects.size(); i++) { - auto type = emailVerificationCodeObjects[i]->getModel()->getType(); - if (type == model::table::EMAIL_OPT_IN_EMPTY || type == model::table::EMAIL_OPT_IN_REGISTER) { - checkEmail = i; - } - else if (type == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { - resetPasswd = i; - } - } - std::unique_lock _lock_shared(mSharedMutex); - if (resetPasswd != -1) { - mEmailVerificationCodeObject = emailVerificationCodeObjects[resetPasswd]; - } - else if (checkEmail != -1) { - mEmailVerificationCodeObject = emailVerificationCodeObjects[checkEmail]; - } - - } - catch (Poco::Exception& ex) { - printf("[Session::detectSessionState] exception: %s\n", ex.displayText().data()); - //return; - } - - if (userState <= USER_EMAIL_NOT_ACTIVATED) { - - if (checkEmail != -1) { - updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN); - return; - } - - updateState(SESSION_STATE_USER_WRITTEN); - return; - } - - if (USER_NO_KEYS == userState) { - - auto user_id = mSessionUser->getDBId(); - auto userBackups = controller::UserBackups::load(user_id); - - // check passphrase, only possible while passphrase isn't crypted in db - bool correctPassphraseFound = false; - // always trigger SESSION_STATE_PASSPHRASE_WRITTEN, else lost of data possible - bool cryptedPassphrase = userBackups.size() > 0; - for (auto it = userBackups.begin(); it != userBackups.end(); it++) { - KeyPair keys; - auto passphrase = (*it)->getModel()->getPassphrase(); - Mnemonic* wordSource = nullptr; - if (User::validatePassphrase(passphrase, &wordSource)) { - if (keys.generateFromPassphrase((*it)->getModel()->getPassphrase().data(), wordSource)) { - if (sodium_memcmp(mSessionUser->getPublicKey(), keys.getPublicKey(), ed25519_pubkey_SIZE) == 0) { - correctPassphraseFound = true; - break; - } - } - } - else { - cryptedPassphrase = true; - } - } - /* - auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement select(dbConnection); - Poco::Nullable passphrase; - - select << "SELECT passphrase from user_backups where user_id = ?;", - into(passphrase), use(user_id); - try { - if (select.execute() == 1 && !passphrase.isNull()) { - //KeyPair keys;keys.generateFromPassphrase(passphrase.value().rawContent()) - updateState(SESSION_STATE_PASSPHRASE_WRITTEN); - return; - } - } - catch (Poco::Exception& exc) { - printf("[Session::detectSessionState] 2 mysql exception: %s\n", exc.displayText().data()); - }*/ - if (correctPassphraseFound || cryptedPassphrase) { - updateState(SESSION_STATE_PASSPHRASE_WRITTEN); - return; - } - if (mPassphrase != "") { - updateState(SESSION_STATE_PASSPHRASE_GENERATED); - return; - } - updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); - return; - } - - updateState(SESSION_STATE_KEY_PAIR_WRITTEN); - - if (resetPasswd != -1) { - // don't go to reset password screen after login, only throw checkEmail - //updateState(SESSION_STATE_RESET_PASSWORD_REQUEST); - return; - } - -} - -Poco::Net::HTTPCookie Session::getLoginCookie() -{ - auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", std::to_string(mHandleId)); - // prevent reading or changing cookie with js -// keks.setHttpOnly(); - - keks.setPath("/"); - // send cookie only via https, on linux, except in test builds -#ifndef WIN32 - if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || - ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { - keks.setSecure(true); - } -#endif - - return keks; -} - -bool Session::loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode) -{ - Profiler usedTime; - auto em = ErrorManager::getInstance(); - std::unique_lock _lock(mSharedMutex); - mEmailVerificationCodeObject = controller::EmailVerificationCode::load(emailVerificationCode); - if (mEmailVerificationCodeObject.isNull()) { - addError(new Error(gettext("E-Mail Verification"), gettext("Konnte kein passendes Konto finden."))); - return false; - } - - mNewUser = controller::User::create(); - assert(mEmailVerificationCodeObject->getModel() && mEmailVerificationCodeObject->getModel()->getUserId()); - mNewUser->load(mEmailVerificationCodeObject->getModel()->getUserId()); - if (mNewUser->getModel()->errorCount() > 0) { - mNewUser->getModel()->sendErrorsAsEmail(); - addError(new Error(gettext("E-Mail Verification"), gettext("Fehler beim laden des Benutzers."))); - return false; - } - mSessionUser = new User(mNewUser); - mSessionUser->setLanguage(getLanguage()); - - auto verificationType = mEmailVerificationCodeObject->getModel()->getType(); - if (verificationType == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { - updateState(SESSION_STATE_RESET_PASSWORD_REQUEST); - } - else { - updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN); - } - - return true; -} - -void Session::updateState(SessionStates newState) -{ - lock("Session::updateState"); - if (!mActive) { - unlock(); - return; - } - updateTimeout(); - //printf("[%s] newState: %s\n", __FUNCTION__, translateSessionStateToString(newState)); - if (newState > mState) { - mState = newState; - } - - unlock(); -} - -const char* Session::getSessionStateString() -{ - SessionStates state; - lock("Session::getSessionStateString"); - state = mState; - unlock(); - return translateSessionStateToString(state); -} - - -const char* Session::translateSessionStateToString(SessionStates state) -{ - switch (state) { - case SESSION_STATE_EMPTY: return "uninitalized"; - case SESSION_STATE_CRYPTO_KEY_GENERATED: return "crpyto key generated"; - case SESSION_STATE_USER_WRITTEN: return "User saved"; - case SESSION_STATE_EMAIL_VERIFICATION_WRITTEN: return "E-Mail verification code saved"; - case SESSION_STATE_EMAIL_VERIFICATION_SEND: return "Verification E-Mail sended"; - case SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED: return "Verification Code checked"; - case SESSION_STATE_PASSPHRASE_GENERATED: return "Passphrase generated"; - case SESSION_STATE_PASSPHRASE_SHOWN: return "Passphrase shown"; - case SESSION_STATE_PASSPHRASE_WRITTEN: return "Passphrase written"; - case SESSION_STATE_KEY_PAIR_GENERATED: return "Gradido Address created"; - case SESSION_STATE_KEY_PAIR_WRITTEN: return "Gradido Address saved"; - case SESSION_STATE_RESET_PASSWORD_REQUEST: return "Passwort reset requested"; - case SESSION_STATE_RESET_PASSWORD_SUCCEED: return "Passwort reset succeeded"; - default: return "unknown"; - } - - return "error"; -} - - -/* -bool Session::useOrGeneratePassphrase(const std::string& passphase) -{ - if (passphase != "" && User::validatePassphrase(passphase)) { - // passphrase is valid - setPassphrase(passphase); - updateState(SESSION_STATE_PASSPHRASE_SHOWN); - return true; - } - else { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); - updateState(SESSION_STATE_PASSPHRASE_GENERATED); - return true; - } -} -*/ -bool Session::generatePassphrase() -{ - if (mNewUser.isNull()) return false; - - auto lang = getLanguage(); - if (lang == LANG_EN) { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); - } - else { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - } - //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - updateState(SESSION_STATE_PASSPHRASE_GENERATED); - return true; -} - -bool Session::generateKeys(bool savePrivkey, bool savePassphrase) -{ - if (mNewUser.isNull()) { - addError(new Error(gettext("Benutzer"), gettext("Kein gültiger Benutzer, bitte logge dich erneut ein."))); - return false; - } - static const char* function_name = "Session::generateKeys"; - auto lang = getLanguage(); - auto user_model = mNewUser->getModel(); - auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - /*if (LANG_DE == lang) { - mnemonic_type = ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES; - }*/ - - auto passphrase = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - if (!passphrase) { - addError(new ParamError(function_name, "Error generating passphrase with mnemonic: ", mnemonic_type)); - addError(new ParamError(function_name, "user email: ", mNewUser->getModel()->getEmail())); - sendErrorsAsEmail(); - addError(new Error(gettext("Benutzer"), gettext("Fehler beim generieren der Passphrase, der Admin bekommt eine E-Mail. "))); - return false; - } - - if (savePassphrase) { - auto user_backup = controller::UserBackups::create(user_model->getID(), passphrase->getString(), mnemonic_type); - // sync version - //user_backup->getModel()->insertIntoDB(false); - - // async version - UniLib::controller::TaskPtr save_user_backup_task = new model::table::ModelInsertTask(user_backup->getModel(), false, true); - save_user_backup_task->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_PASSPHRASE_WRITTEN, this)); - save_user_backup_task->scheduleTask(save_user_backup_task); - } - - // keys - auto gradido_key_pair = KeyPairEd25519::create(passphrase); - auto set_key_result = mNewUser->setGradidoKeyPair(gradido_key_pair); - size_t result_save_key = 0; - if (1 == set_key_result && savePrivkey) { - // save public key and private key in db - result_save_key = user_model->updatePubkeyAndPrivkey(); - } - else { - // save public key in db - result_save_key = user_model->updatePublickey(); - } - if (!result_save_key) { - user_model->addError(new Error(function_name, "Error saving new generated pubkey")); - user_model->addError(new ParamError(function_name, "e-mail: ", user_model->getEmail())); - user_model->sendErrorsAsEmail(); - //addError(new Error(gettext("Benutzer"), gettext("Fehler beim Speichern der Keys, der Admin bekommt eine E-Mail. Evt. nochmal versuchen oder abwarten!"))); - return false; - } - return true; - /* - - bool validUser = true; - if (mSessionUser) { - if (!mSessionUser->generateKeys(savePrivkey, mPassphrase, this)) { - validUser = false; - } - else { - if (savePassphrase) { - //printf("[Session::generateKeys] create save passphrase task\n"); - UniLib::controller::TaskPtr savePassphrase(new WritePassphraseIntoDB(mSessionUser->getDBId(), mPassphrase)); - savePassphrase->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_PASSPHRASE_WRITTEN, this)); - savePassphrase->scheduleTask(savePassphrase); - } - } - } - else { - validUser = false; - } - if (!validUser) { - addError(new Error(gettext("Benutzer"), gettext("Kein gültiger Benutzer, bitte logge dich erneut ein."))); - return false; - } - // delete passphrase after all went well - mPassphrase.clear(); - - return true; - */ -} +#include "Session.h" +#include "../lib/Profiler.h" +#include "../ServerConfig.h" + +#include "Poco/RegularExpression.h" +#include "Poco/Net/StringPartSource.h" +#include "Poco/Net/MediaType.h" + +#include "../SingletonManager/SessionManager.h" +#include "../SingletonManager/ConnectionManager.h" +#include "../SingletonManager/ErrorManager.h" +#include "../SingletonManager/EmailManager.h" +#include "../SingletonManager/SingletonTaskObserver.h" + +#include "../tasks/PrepareEmailTask.h" +#include "../tasks/SendEmailTask.h" +#include "../tasks/SigningTransaction.h" +#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h" +#include "../tasks/VerificationEmailResendTask.h" + +#include "../lib/JsonRequest.h" + +#include "../Crypto/Passphrase.h" + + +#include "../controller/User.h" +#include "../controller/UserBackup.h" +#include "../controller/EmailVerificationCode.h" + +#include "table/ModelBase.h" + + +#include "sodium.h" + +using namespace Poco::Data::Keywords; + +int WriteEmailVerification::run() +{ + auto em = ErrorManager::getInstance(); + + mEmailVerificationCode->getModel()->setUserId(mUser->getDBId()); + auto emailVerificationModel = mEmailVerificationCode->getModel(); + emailVerificationModel->setUserId(mUser->getDBId()); + if (!emailVerificationModel->insertIntoDB(true) || emailVerificationModel->errorCount() > 0) { + emailVerificationModel->sendErrorsAsEmail(); + return -1; + } + + return 0; +} + +// --------------------------------------------------------------------------------------------------------------- + +int WritePassphraseIntoDB::run() +{ + Profiler timeUsed; + + // TODO: encrypt passphrase, need server admin crypto box pubkey + //int crypto_box_seal(unsigned char *c, const unsigned char *m, + //unsigned long long mlen, const unsigned char *pk); + size_t mlen = mPassphrase.size(); + size_t crypto_size = crypto_box_SEALBYTES + mlen; + + auto em = ErrorManager::getInstance(); + + auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement insert(dbSession); + insert << "INSERT INTO user_backups (user_id, passphrase) VALUES(?,?)", + use(mUserId), use(mPassphrase); + try { + if (insert.execute() != 1) { + em->addError(new ParamError("WritePassphraseIntoDB::run", "inserting passphrase for user failed", std::to_string(mUserId))); + em->sendErrorsAsEmail(); + } + } + catch (Poco::Exception& ex) { + em->addError(new ParamError("WritePassphraseIntoDB::run", "insert passphrase mysql error", ex.displayText().data())); + em->sendErrorsAsEmail(); + } + + //printf("[WritePassphraseIntoDB] timeUsed: %s\n", timeUsed.string().data()); + return 0; +} + + +// -------------------------------------------------------------------------------------------------------------- + +Session::Session(int handle) + : mHandleId(handle), mSessionUser(nullptr), mState(SESSION_STATE_EMPTY), mActive(false) +{ + +} + +Session::~Session() +{ + //printf("[Session::~Session] \n"); + if (tryLock()) { + unlock(); + reset(); + } + + + //printf("[Session::~Session] finished \n"); +} + + +void Session::reset() +{ + //printf("[Session::reset]\n"); + lock("Session::reset"); + std::unique_lock _lock(mSharedMutex); + mSessionUser.assign(nullptr); + mNewUser.assign(nullptr); + mEmailVerificationCodeObject.assign(nullptr); + + // watch out + //updateTimeout(); + mLastActivity = Poco::DateTime(); + + mState = SESSION_STATE_EMPTY; + + mPassphrase = ""; + mLastExternReferer = ""; + mClientLoginIP = Poco::Net::IPAddress(); + unlock(); + + // reset transactions + mCurrentActiveProcessingTransaction = nullptr; + mProcessingTransactions.clear(); + + //printf("[Session::reset] finished\n"); +} + +int Session::isActive() +{ + int ret = 0; + try { + mWorkMutex.tryLock(100); + } + catch (Poco::TimeoutException &ex) { + return -1; + } + ret = (int)mActive; + unlock(); + return ret; + +} + +bool Session::isDeadLocked() +{ + try { + mWorkMutex.tryLock(200); + unlock(); + return false; + } + catch (Poco::Exception& ex) { + + } + return true; +} + +bool Session::setActive(bool active) +{ + try { + mWorkMutex.tryLock(100); + } + catch (Poco::TimeoutException &ex) { + return false; + } + mActive = active; + unlock(); + return true; +} + +void Session::updateTimeout() +{ + lock("Session::updateTimeout"); + mLastActivity = Poco::DateTime(); + unlock(); +} + +Poco::AutoPtr Session::getEmailVerificationCodeObject() +{ + lock("Session::getEmailVerificationCodeObject"); + std::shared_lock _lock(mSharedMutex); + auto ret = mEmailVerificationCodeObject; + unlock(); + return ret; +} + +bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email) +{ + Profiler usedTime; + + if (mNewUser->getModel()->getRole() != model::table::ROLE_ADMIN) { + addError(new Error(gettext("Benutzer"), gettext("Eingeloggter Benutzer ist kein Admin")), false); + return false; + } + + auto sm = SessionManager::getInstance(); + if (!sm->isValid(first_name, VALIDATE_NAME)) { + addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); + return false; + } + if (!sm->isValid(last_name, VALIDATE_NAME)) { + addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); + return false; + } + if (!sm->isValid(email, VALIDATE_EMAIL)) { + addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); + return false; + } + + + // check if user with that email already exist + if (mNewUser->getModel()->isExistInDB("email", email)) { + addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits einen Account")), false); + return false; + } + + auto newUser = controller::User::create(email, first_name, last_name); + updateTimeout(); + + + auto newUserModel = newUser->getModel(); + if (!newUserModel->insertIntoDB(true)) { + addError(new Error(gettext("Benutzer"), gettext("Fehler beim speichern!"))); + return false; + } + + auto email_verification_code = controller::EmailVerificationCode::create(newUserModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); + if (!email_verification_code->getModel()->insertIntoDB(false)) { + addError(new Error(gettext("Email Verification Code"), gettext("Fehler beim speichern!"))); + return false; + } + + EmailManager::getInstance()->addEmail(new model::Email(email_verification_code, newUser, model::EMAIL_ADMIN_USER_VERIFICATION_CODE)); + + std::unique_lock _lock(mSharedMutex); + mEmailVerificationCodeObject = email_verification_code; + + + return true; +} +// +bool Session::createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) +{ + Profiler usedTime; + auto sm = SessionManager::getInstance(); + if (!sm->isValid(first_name, VALIDATE_NAME)) { + addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); + return false; + } + if (!sm->isValid(last_name, VALIDATE_NAME)) { + addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); + return false; + } + if (!sm->isValid(email, VALIDATE_EMAIL)) { + addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); + return false; + } + if (!sm->checkPwdValidation(password, this)) { + return false; + } + /*if (passphrase.size() > 0 && !sm->isValid(passphrase, VALIDATE_PASSPHRASE)) { + addError(new Error("Merkspruch", "Der Merkspruch ist nicht gültig, er besteht aus 24 Wörtern, mit Komma getrennt.")); + return false; + } + if (passphrase.size() == 0) { + //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); + mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); + } + else { + //mPassphrase = passphrase; + }*/ + + // check if user with that email already exist + + auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(dbConnection); + select << "SELECT email from users where email = ?;", useRef(email); + try { + if (select.execute() > 0) { + addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits einen Account")), false); + return false; + } + } + catch (Poco::Exception& exc) { + printf("mysql exception: %s\n", exc.displayText().data()); + } + + mSessionUser = new User(email.data(), first_name.data(), last_name.data()); + mNewUser = controller::User::create(email, first_name, last_name); + updateTimeout(); + + // Prepare E-Mail + //UniLib::controller::TaskPtr prepareEmail(new PrepareEmailTask(ServerConfig::g_CPUScheduler)); + //prepareEmail->scheduleTask(prepareEmail); + + // create user crypto key + UniLib::controller::TaskPtr cryptoKeyTask(new UserCreateCryptoKey(mSessionUser, mNewUser, password, ServerConfig::g_CryptoCPUScheduler)); + cryptoKeyTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_CRYPTO_KEY_GENERATED, this)); + cryptoKeyTask->scheduleTask(cryptoKeyTask); + + // depends on crypto key, write user record into db + UniLib::controller::TaskPtr writeUserIntoDB(new UserWriteIntoDB(mSessionUser, ServerConfig::g_CPUScheduler, 1)); + writeUserIntoDB->setParentTaskPtrInArray(cryptoKeyTask, 0); + writeUserIntoDB->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_USER_WRITTEN, this)); + writeUserIntoDB->scheduleTask(writeUserIntoDB); + + std::unique_lock _lock(mSharedMutex); + mEmailVerificationCodeObject = controller::EmailVerificationCode::create(model::table::EMAIL_OPT_IN_REGISTER); + UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, mEmailVerificationCodeObject, ServerConfig::g_CPUScheduler, 1)); + + writeEmailVerification->setParentTaskPtrInArray(writeUserIntoDB, 0); + writeEmailVerification->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, this)); + writeEmailVerification->scheduleTask(writeEmailVerification); + + + /*printf("LastName: %s\n", last_name.data()); + for (int i = 0; i < last_name.size(); i++) { + char c = last_name.data()[i]; + //printf("%d ", c); + } + //printf("\n\n"); + */ + + // depends on writeUser because need user_id, write email verification into db + /*auto message = new Poco::Net::MailMessage; + Poco::Net::MediaType mt("text", "plain"); + mt.setParameter("charset", "utf-8"); + message->setContentType(mt); + + message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, email)); + message->setSubject(gettext("Gradido: E-Mail Verification")); + std::stringstream ss; + ss << "Hallo " << first_name << " " << last_name << "," << std::endl << std::endl; + ss << "Du oder jemand anderes hat sich soeben mit dieser E-Mail Adresse bei Gradido registriert. " << std::endl; + ss << "Wenn du es warst, klicke bitte auf den Link: " << ServerConfig::g_serverPath << "/checkEmail/" << mEmailVerificationCode << std::endl; + //ss << "oder kopiere den Code: " << mEmailVerificationCode << " selbst dort hinein." << std::endl; + ss << "oder kopiere den obigen Link in Dein Browserfenster." << std::endl; + ss << std::endl; + ss << "Mit freundlichen " << u8"Grüßen" << std::endl; + ss << "Dario, Gradido Server Admin" << std::endl; + + + message->addContent(new Poco::Net::StringPartSource(ss.str())); + */ + //UniLib::controller::TaskPtr sendEmail(new SendEmailTask(message, ServerConfig::g_CPUScheduler, 1)); + //Email(AutoPtr emailVerification, AutoPtr user, EmailType type); + UniLib::controller::TaskPtr sendEmail(new SendEmailTask(new model::Email(mEmailVerificationCodeObject, mNewUser, model::EMAIL_USER_VERIFICATION_CODE), ServerConfig::g_CPUScheduler, 1)); + //sendEmail->setParentTaskPtrInArray(prepareEmail, 0); + sendEmail->setParentTaskPtrInArray(writeEmailVerification, 0); + sendEmail->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_SEND, this)); + sendEmail->scheduleTask(sendEmail); + + // write user into db + // generate and write email verification into db + // send email + + //printf("[Session::createUser] time: %s\n", usedTime.string().data()); + + return true; +} + +bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) +{ + std::unique_lock _lock(mSharedMutex); + static const char* function_name = "Session::createUserDirect"; + auto sm = SessionManager::getInstance(); + auto em = ErrorManager::getInstance(); + auto email_manager = EmailManager::getInstance(); + + if (!sm->isValid(first_name, VALIDATE_NAME)) { + addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); + return false; + } + if (!sm->isValid(last_name, VALIDATE_NAME)) { + addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false); + return false; + } + if (!sm->isValid(email, VALIDATE_EMAIL)) { + addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false); + return false; + } + if (!sm->checkPwdValidation(password, this)) { + return false; + } + + // check if email already exist + auto user = controller::User::create(); + if (user->load(email) >= 1) { + addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits ein Konto")), false); + return false; + } + + // user + mNewUser = controller::User::create(email, first_name, last_name); + auto user_model = mNewUser->getModel(); + user_model->insertIntoDB(true); + auto user_id = user_model->getID(); + + + // one retry in case of connection error + if (!user_id) { + user_model->insertIntoDB(true); + auto user_id = user_model->getID(); + if (!user_id) { + em->addError(new ParamError(function_name, "error saving new user in db, after one retry with email", email)); + em->sendErrorsAsEmail(); + addError(new Error(gettext("Server"), gettext("Fehler beim speichen des Kontos bitte versuche es später noch einmal")), false); + return false; + } + } + + generateKeys(true, true); + + // calculate encryption key, could need some time, will save encrypted privkey to db + UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(mNewUser, password); + create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); + + // email verification code + auto email_verification = controller::EmailVerificationCode::create(user_id, model::table::EMAIL_OPT_IN_REGISTER_DIRECT); + email_verification->getModel()->insertIntoDB(false); + mEmailVerificationCodeObject = email_verification; + + auto _7days_later = Poco::DateTime() + Poco::Timespan(7, 0, 0, 0, 0); + ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(_7days_later.timestamp())); + + email_manager->addEmail(new model::Email(email_verification, mNewUser, model::EMAIL_USER_VERIFICATION_CODE)); + + return true; +} + +bool Session::ifUserExist(const std::string& email) +{ + auto em = ErrorManager::getInstance(); + const char* funcName = "Session::ifUserExist"; + auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(dbConnection); + bool emailChecked = false; + int userId = 0; + select << "SELECT email_checked, id from users where email = ? and email_checked = 1", + into(emailChecked), into(userId), useRef(email); + + try { + if(select.execute() == 1) return true; + } + catch (Poco::Exception& ex) { + em->addError(new ParamError(funcName, "select user from email verification code mysql error ", ex.displayText().data())); + em->sendErrorsAsEmail(); + } + return false; +} + +int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) +{ + const static char* funcName = "Session::updateEmailVerification"; + Poco::ScopedLock _lock(mWorkMutex); + // new mutex, will replace the Poco Mutex complete in the future + std::unique_lock _lock_shared(mSharedMutex); + Profiler usedTime; + + auto em = ErrorManager::getInstance(); + if (mEmailVerificationCodeObject.isNull()) { + em->addError(new Error(funcName, "email verification object is zero")); + em->sendErrorsAsEmail(); + + return -2; + } + auto email_verification_code_model = mEmailVerificationCodeObject->getModel(); + assert(email_verification_code_model); + if(email_verification_code_model->getCode() == emailVerificationCode) { + if (mSessionUser && mSessionUser->getDBId() == 0) { + //addError(new Error("E-Mail Verification", "Benutzer wurde nicht richtig gespeichert, bitte wende dich an den Server-Admin")); + em->addError(new Error(funcName, "user exist with 0 as id")); + em->sendErrorsAsEmail(); + + //return false; + return -2; + } + + // load correct user from db + if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getModel()->getID() != email_verification_code_model->getUserId()) { + mNewUser = controller::User::create(); + if (1 != mNewUser->load(email_verification_code_model->getUserId())) { + em->addError(new ParamError(funcName, "user load didn't return 1 with user_id ", email_verification_code_model->getUserId())); + em->sendErrorsAsEmail(); + + return -2; + } + } + + auto user_model = mNewUser->getModel(); + assert(user_model); + bool first_email_activation = false; + auto verification_type = email_verification_code_model->getType(); + if (model::table::EMAIL_OPT_IN_REGISTER == verification_type || + model::table::EMAIL_OPT_IN_EMPTY == verification_type || + model::table::EMAIL_OPT_IN_REGISTER_DIRECT == verification_type) { + first_email_activation = true; + } + if (first_email_activation && user_model->isEmailChecked()) { + mSessionUser = new User(mNewUser); + addError(new Error(gettext("E-Mail Verification"), gettext("Du hast dein Konto bereits aktiviert!")), false); + + return 1; + } + if (first_email_activation) { + user_model->setEmailChecked(true); + + user_model->updateIntoDB("email_checked", 1); + if (user_model->errorCount() > 0) { + user_model->sendErrorsAsEmail(); + } + + // no find all active sessions + + updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); + return 0; + } + + if (email_verification_code_model->getType() == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { + + if (mEmailVerificationCodeObject->deleteFromDB()) { + mEmailVerificationCodeObject.assign(nullptr); + } + else { + em->getErrors(mEmailVerificationCodeObject->getModel()); + em->addError(new Error(funcName, "error deleting email verification code")); + em->sendErrorsAsEmail(); + return -2; + } + updateState(SESSION_STATE_RESET_PASSWORD_REQUEST); + return 0; + } + + em->addError(new Error(funcName, "invalid code path")); + em->sendErrorsAsEmail(); + + return -2; + + /*if (updated_rows == 1) { + Poco::Data::Statement delete_row(dbConnection); + delete_row << "DELETE FROM email_opt_in where verification_code = ?", use(emailVerificationCode); + if (delete_row.execute() != 1) { + em->addError(new Error(funcName, "delete from email_opt_in entry didn't work as expected, please check db")); + em->sendErrorsAsEmail(); + } + if (mSessionUser) { + mSessionUser->setEmailChecked(); + mSessionUser->setLanguage(getLanguage()); + } + updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); + //printf("[%s] time: %s\n", funcName, usedTime.string().data()); + unlock(); + return true; + } + else { + em->addError(new ParamError(funcName, "update user work not like expected, updated row count", updated_rows)); + em->sendErrorsAsEmail(); + }*/ + + + } + else { + addError(new Error(gettext("E-Mail Verification"), gettext("Falscher Code für aktiven Login"))); + //printf("[%s] time: %s\n", funcName, usedTime.string().data()); + + return -1; + } + //printf("[%s] time: %s\n", funcName, usedTime.string().data()); + + return 0; +} + + +int Session::sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized) +{ + mNewUser = user; + mSessionUser = new User(user); + auto em = EmailManager::getInstance(); + + std::unique_lock _lock(mSharedMutex); + + // creating email verification code also for user without passphrase + // first check if already exist + // check if email was already send shortly before + bool frequent_resend = false; + bool email_already_send = false; + + mEmailVerificationCodeObject = controller::EmailVerificationCode::load(user->getModel()->getID(), model::table::EMAIL_OPT_IN_RESET_PASSWORD); + if (mEmailVerificationCodeObject.isNull()) { + mEmailVerificationCodeObject = controller::EmailVerificationCode::create(mNewUser->getModel()->getID(), model::table::EMAIL_OPT_IN_RESET_PASSWORD); + mEmailVerificationCodeObject->getModel()->insertIntoDB(false); + } + else { + email_already_send = true; + } + auto email_verification_model = mEmailVerificationCodeObject->getModel(); + if (email_already_send) { + auto time_elapsed = Poco::DateTime() - email_verification_model->getUpdated(); + if (time_elapsed.totalHours() < 1) { + frequent_resend = true; + } + } + + if (!frequent_resend) { + if (passphraseMemorized) { + em->addEmail(new model::Email(mEmailVerificationCodeObject, mNewUser, model::EMAIL_USER_RESET_PASSWORD)); + } + else { + em->addEmail(new model::Email(user, model::EMAIL_ADMIN_RESET_PASSWORD_REQUEST_WITHOUT_MEMORIZED_PASSPHRASE)); + } + } + + if (frequent_resend) return 2; + if (email_already_send) return 1; + + return 0; +} + +int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource) +{ + KeyPair keys; + static const char* functionName = "Session::comparePassphraseWithSavedKeys"; + if (!wordSource) { + addError(new Error(functionName, "wordSource is empty")); + sendErrorsAsEmail(); + return -2; + } + if (!keys.generateFromPassphrase(inputPassphrase.data(), wordSource)) { + addError(new ParamError(functionName, "invalid passphrase", inputPassphrase)); + if (!mNewUser.isNull() && mNewUser->getModel()) { + addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); + } + sendErrorsAsEmail(); + addError(new Error(gettext("Passphrase"), gettext("Deine Passphrase ist ungütig")), false); + return 0; + } + auto userModel = mNewUser->getModel(); + auto existingPublic = userModel->getPublicKey(); + if (!existingPublic) { + userModel->loadFromDB("email", userModel->getEmail()); + existingPublic = userModel->getPublicKey(); + if (!existingPublic) { + addError(new Error(functionName, "cannot load existing public key from db")); + addError(new ParamError(functionName, "user email", userModel->getEmail())); + sendErrorsAsEmail(); + addError(new Error(gettext("Passphrase"), gettext("Ein Fehler trat auf, bitte versuche es erneut")), false); + return -1; + } + } + if (0 == memcmp(userModel->getPublicKey(), keys.getPublicKey(), crypto_sign_PUBLICKEYBYTES)) { + mPassphrase = inputPassphrase; + return 1; + } + addError(new Error(gettext("Passphrase"), gettext("Das ist nicht die richtige Passphrase.")), false); + return 0; +} + +bool Session::startProcessingTransaction(const std::string& proto_message_base64, bool autoSign/* = false*/) +{ + static const char* funcName = "Session::startProcessingTransaction"; + lock(funcName); + HASH hs = ProcessingTransaction::calculateHash(proto_message_base64); + // check if it is already running or waiting + for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { + if (it->isNull()) { + it = mProcessingTransactions.erase(it); + } + if (hs == (*it)->getHash()) { + addError(new Error(funcName, "transaction already in list")); + unlock(); + return false; + } + } + if (mSessionUser.isNull() || !mSessionUser->getEmail()) { + addError(new Error(funcName, "user is zero")); + unlock(); + return false; + } + + Poco::AutoPtr processorTask( + new ProcessingTransaction( + proto_message_base64, + DRMakeStringHash(mSessionUser->getEmail()), + mSessionUser->getLanguage()) + ); + if (autoSign && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) == ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) { + if (processorTask->run() != 0) { + getErrors(processorTask); + unlock(); + return false; + } + Poco::AutoPtr signingTransaction(new SigningTransaction(processorTask, mNewUser)); + //signingTransaction->scheduleTask(signingTransaction); + if (signingTransaction->run() != 0) { + getErrors(signingTransaction); + unlock(); + return false; + } + + } + else { + processorTask->scheduleTask(processorTask); + mProcessingTransactions.push_back(processorTask); + } + unlock(); + return true; + +} + +Poco::AutoPtr Session::getNextReadyTransaction(size_t* working/* = nullptr*/) +{ + lock("Session::getNextReadyTransaction"); + if (working) { + *working = 0; + } + else if (!mCurrentActiveProcessingTransaction.isNull()) + { + unlock(); + return mCurrentActiveProcessingTransaction; + } + for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { + if (working && !(*it)->isTaskFinished()) { + (*working)++; + } + if (mCurrentActiveProcessingTransaction.isNull() && (*it)->isTaskFinished()) { + if (!working) { + mCurrentActiveProcessingTransaction = *it; + unlock(); + return mCurrentActiveProcessingTransaction; + } + // no early exit + else { + mCurrentActiveProcessingTransaction = *it; + } + + } + } + unlock(); + return mCurrentActiveProcessingTransaction; +} + +bool Session::finalizeTransaction(bool sign, bool reject) +{ + int result = -1; + lock("Session::finalizeTransaction"); + if (mCurrentActiveProcessingTransaction.isNull()) { + unlock(); + return false; + } + mProcessingTransactions.remove(mCurrentActiveProcessingTransaction); + + if (!reject) { + if (sign) { + Poco::AutoPtr signingTransaction(new SigningTransaction(mCurrentActiveProcessingTransaction, mNewUser)); + //signingTransaction->scheduleTask(signingTransaction); + result = signingTransaction->run(); + } + } + mCurrentActiveProcessingTransaction.assign(nullptr); + unlock(); + return result == 0; +} + +size_t Session::getProcessingTransactionCount() +{ + size_t count = 0; + lock("Session::getProcessingTransactionCount"); + + for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { + + (*it)->lock(); + if ((*it)->errorCount() > 0) { + (*it)->sendErrorsAsEmail(); + (*it)->unlock(); + it = mProcessingTransactions.erase(it); + if (it == mProcessingTransactions.end()) break; + } + else { + (*it)->unlock(); + } + + } + count = mProcessingTransactions.size(); + unlock(); + return count; +} + +bool Session::isPwdValid(const std::string& pwd) +{ + if (mSessionUser) { + return mSessionUser->validatePwd(pwd, this); + } + return false; +} + +UserStates Session::loadUser(const std::string& email, const std::string& password) +{ + static const char* functionName = "Session::loadUser"; + auto observer = SingletonTaskObserver::getInstance(); + if (email != "") { + if (observer->getTaskCount(email, TASK_OBSERVER_PASSWORD_CREATION) > 0) { + return USER_PASSWORD_ENCRYPTION_IN_PROCESS; + } + } + //Profiler usedTime; + //printf("before lock\n"); + lock(functionName); + //printf("locked \n"); + if (!mSessionUser.isNull() && mSessionUser->getEmail() != email) { + mSessionUser.assign(nullptr); + mNewUser.assign(nullptr); + //printf("user nullptr assigned\n"); + } + //printf("after checking if session user is null\n"); + //if (!mSessionUser) { + if (mNewUser.isNull()) { + //printf("new user is null\n"); + mNewUser = controller::User::create(); + //printf("new user created\n"); + // load user for email only once from db + mNewUser->load(email); + //printf("load new user from db with email: %s\n", email.data()); + mSessionUser = new User(mNewUser); + //mSessionUser = new User(email.data()); + + //printf("user loaded from email\n"); + } + //printf("before get model\n"); + auto user_model = mNewUser->getModel(); + if (user_model && user_model->isDisabled()) { + return USER_DISABLED; + } + //printf("before if login\n"); + if (!mSessionUser.isNull() && mSessionUser->getUserState() >= USER_LOADED_FROM_DB) { + //printf("before login\n"); + int loginResult = 0; + int exitCount = 0; + do { + loginResult = mNewUser->login(password); + Poco::Thread::sleep(100); + exitCount++; + } while (-3 == loginResult && exitCount < 15); + if (exitCount > 1) { + addError(new ParamError(functionName, "login succeed, retrys: ", exitCount)); + addError(new ParamError(functionName, "email: ", email)); + sendErrorsAsEmail(); + } + + if (exitCount >= 15) + { + auto running_password_creations = observer->getTasksCount(TASK_OBSERVER_PASSWORD_CREATION); + + addError(new ParamError(functionName, "login failed after 15 retrys and 100 ms sleep between, currently running passwort creation tasks: ", running_password_creations)); + addError(new ParamError(functionName, "email: ", email)); + sendErrorsAsEmail(); + return USER_PASSWORD_ENCRYPTION_IN_PROCESS; + } + + //printf("new user login with result: %d\n", loginResult); + + if (-1 == loginResult) { + addError(new Error(functionName, "error in user data set, saved pubkey didn't match extracted pubkey from private key")); + addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); + sendErrorsAsEmail(); + //unlock(); + //return USER_KEYS_DONT_MATCH; + } + if (0 == loginResult) { + unlock(); + return USER_PASSWORD_INCORRECT; + } + // error decrypting private key + if (-2 == loginResult) { + // check if we have access to the passphrase, if so we can reencrypt the private key + printf("try reencrypting key\n"); + auto user_model = mNewUser->getModel(); + auto user_backups = controller::UserBackup::load(user_model->getID()); + for (auto it = user_backups.begin(); it != user_backups.end(); it++) { + auto key = std::unique_ptr((*it)->createGradidoKeyPair()); + if (key->isTheSame(user_model->getPublicKey())) + { + + // set valid key pair + if (1 == mNewUser->setGradidoKeyPair(key.release())) { + // save new encrypted private key + user_model->updatePrivkey(); + } + else { + auto em = ErrorManager::getInstance(); + em->addError(new Error(functionName, "error reencrypt private key")); + em->addError(new ParamError(functionName, "for user with email", user_model->getEmail())); + em->sendErrorsAsEmail(); + } + break; + } + } + } + // can be removed if session user isn't used any more + // don't calculate password two times anymore + mSessionUser->login(mNewUser); + //printf("after old user login\n"); + /*if (mNewUser->getModel()->getPasswordHashed() && !mSessionUser->validatePwd(password, this)) { + unlock(); + return USER_PASSWORD_INCORRECT; + }*/ + } + else { + //printf("before sleep\n"); + User::fakeCreateCryptoKey(); + } + + /*if (!mSessionUser->validatePwd(password, this)) { + addError(new Error("Login", "E-Mail oder Passwort nicht korrekt, bitte versuche es erneut!")); + unlock(); + return false; + } + if (!mSessionUser->isEmailChecked()) { + addError(new Error("Account", "E-Mail Adresse wurde noch nicht bestätigt, hast du schon eine E-Mail erhalten?")); + unlock(); + return false; + }*/ + //printf("before detect session state\n"); + detectSessionState(); + unlock(); + //printf("before return user state\n"); + return mSessionUser->getUserState(); +} + +bool Session::deleteUser() +{ + lock("Session::deleteUser"); + bool bResult = false; + if(mSessionUser) { + JsonRequest phpServerRequest(ServerConfig::g_php_serverHost, 443); + Poco::Net::NameValueCollection payload; + payload.add("user", std::string(mSessionUser->getPublicKeyHex())); + //auto ret = phpServerRequest.request("userDelete", payload); + JsonRequestReturn ret = JSON_REQUEST_RETURN_OK; + if (ret == JSON_REQUEST_RETURN_ERROR) { + addError(new Error("Session::deleteUser", "php server error")); + getErrors(&phpServerRequest); + sendErrorsAsEmail(); + } + else if (ret == JSON_REQUEST_RETURN_OK) { + bResult = mSessionUser->deleteFromDB(); + } + else { + addError(new Error(gettext("Benutzer"), gettext("Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."))); + unlock(); + return false; + } + } + if(!bResult) { + addError(new Error(gettext("Benutzer"), gettext("Fehler beim Löschen des Accounts. Bitte logge dich erneut ein und versuche es nochmal."))); + } + unlock(); + return bResult; +} + +void Session::setLanguage(Languages lang) +{ + //printf("[Session::setLanguage] new language: %d\n", lang); + lock("Session::setLanguage"); + if (mLanguageCatalog.isNull() || mLanguageCatalog->getLanguage() != lang) { + auto lm = LanguageManager::getInstance(); + mLanguageCatalog = lm->getFreeCatalog(lang); + } + unlock(); +} + +Languages Session::getLanguage() +{ + Languages lang = LANG_NULL; + lock("Session::getLanguage"); + if (!mLanguageCatalog.isNull()) { + lang = mLanguageCatalog->getLanguage(); + } + unlock(); + return lang; +} + + +/* +SESSION_STATE_CRYPTO_KEY_GENERATED, +SESSION_STATE_USER_WRITTEN, +SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, +SESSION_STATE_EMAIL_VERIFICATION_SEND, +SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED, +SESSION_STATE_PASSPHRASE_GENERATED, +SESSION_STATE_PASSPHRASE_SHOWN, +SESSION_STATE_PASSPHRASE_WRITTEN, +SESSION_STATE_KEY_PAIR_GENERATED, +SESSION_STATE_KEY_PAIR_WRITTEN, +SESSION_STATE_COUNT +*/ +void Session::detectSessionState() +{ + if (mSessionUser.isNull() || !mSessionUser->hasCryptoKey()) { + return; + } + UserStates userState = mSessionUser->getUserState(); + + int checkEmail = -1, resetPasswd = -1; + try { + auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mSessionUser->getDBId()); + + for (int i = 0; i < emailVerificationCodeObjects.size(); i++) { + auto type = emailVerificationCodeObjects[i]->getModel()->getType(); + if (type == model::table::EMAIL_OPT_IN_EMPTY || type == model::table::EMAIL_OPT_IN_REGISTER) { + checkEmail = i; + } + else if (type == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { + resetPasswd = i; + } + } + std::unique_lock _lock_shared(mSharedMutex); + if (resetPasswd != -1) { + mEmailVerificationCodeObject = emailVerificationCodeObjects[resetPasswd]; + } + else if (checkEmail != -1) { + mEmailVerificationCodeObject = emailVerificationCodeObjects[checkEmail]; + } + + } + catch (Poco::Exception& ex) { + printf("[Session::detectSessionState] exception: %s\n", ex.displayText().data()); + //return; + } + + if (userState <= USER_EMAIL_NOT_ACTIVATED) { + + if (checkEmail != -1) { + updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN); + return; + } + + updateState(SESSION_STATE_USER_WRITTEN); + return; + } + + if (USER_NO_KEYS == userState) { + + auto user_id = mSessionUser->getDBId(); + auto userBackups = controller::UserBackup::load(user_id); + + // check passphrase, only possible while passphrase isn't crypted in db + bool correctPassphraseFound = false; + // always trigger SESSION_STATE_PASSPHRASE_WRITTEN, else lost of data possible + bool cryptedPassphrase = userBackups.size() > 0; + for (auto it = userBackups.begin(); it != userBackups.end(); it++) { + KeyPair keys; + auto passphrase = (*it)->getModel()->getPassphrase(); + Mnemonic* wordSource = nullptr; + if (User::validatePassphrase(passphrase, &wordSource)) { + if (keys.generateFromPassphrase((*it)->getModel()->getPassphrase().data(), wordSource)) { + if (sodium_memcmp(mSessionUser->getPublicKey(), keys.getPublicKey(), ed25519_pubkey_SIZE) == 0) { + correctPassphraseFound = true; + break; + } + } + } + else { + cryptedPassphrase = true; + } + } + /* + auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(dbConnection); + Poco::Nullable passphrase; + + select << "SELECT passphrase from user_backups where user_id = ?;", + into(passphrase), use(user_id); + try { + if (select.execute() == 1 && !passphrase.isNull()) { + //KeyPair keys;keys.generateFromPassphrase(passphrase.value().rawContent()) + updateState(SESSION_STATE_PASSPHRASE_WRITTEN); + return; + } + } + catch (Poco::Exception& exc) { + printf("[Session::detectSessionState] 2 mysql exception: %s\n", exc.displayText().data()); + }*/ + if (correctPassphraseFound || cryptedPassphrase) { + updateState(SESSION_STATE_PASSPHRASE_WRITTEN); + return; + } + if (mPassphrase != "") { + updateState(SESSION_STATE_PASSPHRASE_GENERATED); + return; + } + updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED); + return; + } + + updateState(SESSION_STATE_KEY_PAIR_WRITTEN); + + if (resetPasswd != -1) { + // don't go to reset password screen after login, only throw checkEmail + //updateState(SESSION_STATE_RESET_PASSWORD_REQUEST); + return; + } + +} + +Poco::Net::HTTPCookie Session::getLoginCookie() +{ + auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", std::to_string(mHandleId)); + // prevent reading or changing cookie with js +// keks.setHttpOnly(); + + keks.setPath("/"); + // send cookie only via https, on linux, except in test builds +#ifndef WIN32 + if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || + ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { + keks.setSecure(true); + } +#endif + + return keks; +} + +bool Session::loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode) +{ + Profiler usedTime; + auto em = ErrorManager::getInstance(); + std::unique_lock _lock(mSharedMutex); + mEmailVerificationCodeObject = controller::EmailVerificationCode::load(emailVerificationCode); + if (mEmailVerificationCodeObject.isNull()) { + addError(new Error(gettext("E-Mail Verification"), gettext("Konnte kein passendes Konto finden."))); + return false; + } + + mNewUser = controller::User::create(); + assert(mEmailVerificationCodeObject->getModel() && mEmailVerificationCodeObject->getModel()->getUserId()); + mNewUser->load(mEmailVerificationCodeObject->getModel()->getUserId()); + if (mNewUser->getModel()->errorCount() > 0) { + mNewUser->getModel()->sendErrorsAsEmail(); + addError(new Error(gettext("E-Mail Verification"), gettext("Fehler beim laden des Benutzers."))); + return false; + } + mSessionUser = new User(mNewUser); + mSessionUser->setLanguage(getLanguage()); + + auto verificationType = mEmailVerificationCodeObject->getModel()->getType(); + if (verificationType == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { + updateState(SESSION_STATE_RESET_PASSWORD_REQUEST); + } + else { + updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN); + } + + return true; +} + +void Session::updateState(SessionStates newState) +{ + lock("Session::updateState"); + if (!mActive) { + unlock(); + return; + } + updateTimeout(); + //printf("[%s] newState: %s\n", __FUNCTION__, translateSessionStateToString(newState)); + if (newState > mState) { + mState = newState; + } + + unlock(); +} + +const char* Session::getSessionStateString() +{ + SessionStates state; + lock("Session::getSessionStateString"); + state = mState; + unlock(); + return translateSessionStateToString(state); +} + + +const char* Session::translateSessionStateToString(SessionStates state) +{ + switch (state) { + case SESSION_STATE_EMPTY: return "uninitalized"; + case SESSION_STATE_CRYPTO_KEY_GENERATED: return "crpyto key generated"; + case SESSION_STATE_USER_WRITTEN: return "User saved"; + case SESSION_STATE_EMAIL_VERIFICATION_WRITTEN: return "E-Mail verification code saved"; + case SESSION_STATE_EMAIL_VERIFICATION_SEND: return "Verification E-Mail sended"; + case SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED: return "Verification Code checked"; + case SESSION_STATE_PASSPHRASE_GENERATED: return "Passphrase generated"; + case SESSION_STATE_PASSPHRASE_SHOWN: return "Passphrase shown"; + case SESSION_STATE_PASSPHRASE_WRITTEN: return "Passphrase written"; + case SESSION_STATE_KEY_PAIR_GENERATED: return "Gradido Address created"; + case SESSION_STATE_KEY_PAIR_WRITTEN: return "Gradido Address saved"; + case SESSION_STATE_RESET_PASSWORD_REQUEST: return "Passwort reset requested"; + case SESSION_STATE_RESET_PASSWORD_SUCCEED: return "Passwort reset succeeded"; + default: return "unknown"; + } + + return "error"; +} + + +/* +bool Session::useOrGeneratePassphrase(const std::string& passphase) +{ + if (passphase != "" && User::validatePassphrase(passphase)) { + // passphrase is valid + setPassphrase(passphase); + updateState(SESSION_STATE_PASSPHRASE_SHOWN); + return true; + } + else { + mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); + updateState(SESSION_STATE_PASSPHRASE_GENERATED); + return true; + } +} +*/ +bool Session::generatePassphrase() +{ + if (mNewUser.isNull()) return false; + + auto lang = getLanguage(); + if (lang == LANG_EN) { + mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); + } + else { + mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); + } + //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); + updateState(SESSION_STATE_PASSPHRASE_GENERATED); + return true; +} + +bool Session::generateKeys(bool savePrivkey, bool savePassphrase) +{ + if (mNewUser.isNull()) { + addError(new Error(gettext("Benutzer"), gettext("Kein gültiger Benutzer, bitte logge dich erneut ein."))); + return false; + } + static const char* function_name = "Session::generateKeys"; + auto lang = getLanguage(); + auto user_model = mNewUser->getModel(); + auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + /*if (LANG_DE == lang) { + mnemonic_type = ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES; + }*/ + + auto passphrase = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + if (!passphrase) { + addError(new ParamError(function_name, "Error generating passphrase with mnemonic: ", mnemonic_type)); + addError(new ParamError(function_name, "user email: ", mNewUser->getModel()->getEmail())); + sendErrorsAsEmail(); + addError(new Error(gettext("Benutzer"), gettext("Fehler beim generieren der Passphrase, der Admin bekommt eine E-Mail. "))); + return false; + } + + if (savePassphrase) { + auto user_backup = controller::UserBackup::create(user_model->getID(), passphrase->getString(), mnemonic_type); + // sync version + //user_backup->getModel()->insertIntoDB(false); + + // async version + UniLib::controller::TaskPtr save_user_backup_task = new model::table::ModelInsertTask(user_backup->getModel(), false, true); + save_user_backup_task->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_PASSPHRASE_WRITTEN, this)); + save_user_backup_task->scheduleTask(save_user_backup_task); + } + + // keys + auto gradido_key_pair = KeyPairEd25519::create(passphrase); + auto set_key_result = mNewUser->setGradidoKeyPair(gradido_key_pair); + size_t result_save_key = 0; + if (1 == set_key_result && savePrivkey) { + // save public key and private key in db + result_save_key = user_model->updatePubkeyAndPrivkey(); + } + else { + // save public key in db + result_save_key = user_model->updatePublickey(); + } + if (!result_save_key) { + user_model->addError(new Error(function_name, "Error saving new generated pubkey")); + user_model->addError(new ParamError(function_name, "e-mail: ", user_model->getEmail())); + user_model->sendErrorsAsEmail(); + //addError(new Error(gettext("Benutzer"), gettext("Fehler beim Speichern der Keys, der Admin bekommt eine E-Mail. Evt. nochmal versuchen oder abwarten!"))); + return false; + } + return true; + /* + + bool validUser = true; + if (mSessionUser) { + if (!mSessionUser->generateKeys(savePrivkey, mPassphrase, this)) { + validUser = false; + } + else { + if (savePassphrase) { + //printf("[Session::generateKeys] create save passphrase task\n"); + UniLib::controller::TaskPtr savePassphrase(new WritePassphraseIntoDB(mSessionUser->getDBId(), mPassphrase)); + savePassphrase->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_PASSPHRASE_WRITTEN, this)); + savePassphrase->scheduleTask(savePassphrase); + } + } + } + else { + validUser = false; + } + if (!validUser) { + addError(new Error(gettext("Benutzer"), gettext("Kein gültiger Benutzer, bitte logge dich erneut ein."))); + return false; + } + // delete passphrase after all went well + mPassphrase.clear(); + + return true; + */ +} diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index 27539ecf1..80763d337 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -12,7 +12,7 @@ #include "../SingletonManager/LanguageManager.h" #include "../SingletonManager/SingletonTaskObserver.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "Poco/Data/Binding.h" @@ -1090,7 +1090,7 @@ MemoryBin* User::sign(const unsigned char* message, size_t messageSize) //addError(new Error("User::sign", "decrypt privkey failed")); - auto userBackups = controller::UserBackups::load(mDBId); + auto userBackups = controller::UserBackup::load(mDBId); // get privkey, only possible while passphrase isn't crypted in db bool correctPassphraseFound = false; diff --git a/src/cpp/model/table/CryptoKeys.cpp b/src/cpp/model/table/CryptoKey.cpp similarity index 75% rename from src/cpp/model/table/CryptoKeys.cpp rename to src/cpp/model/table/CryptoKey.cpp index e159f51cc..201047a5b 100644 --- a/src/cpp/model/table/CryptoKeys.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -1,20 +1,20 @@ -#include "CryptoKeys.h" +#include "CryptoKey.h" #include "../../lib/DataTypeConverter.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - CryptoKeys::CryptoKeys() + CryptoKey::CryptoKey() { } - CryptoKeys::~CryptoKeys() + CryptoKey::~CryptoKey() { } - std::string CryptoKeys::toString() + std::string CryptoKey::toString() { assert(mKeyType < KEY_TYPE_COUNT && mKeyType >= 0); std::stringstream ss; @@ -24,7 +24,7 @@ namespace model { } - const char* CryptoKeys::typeToString(KeyType type) + const char* CryptoKey::typeToString(KeyType type) { switch (type) { case KEY_TYPE_ED25519_REF10: return "ed25519 ref10"; @@ -33,7 +33,7 @@ namespace model { return ""; } - Poco::Data::Statement CryptoKeys::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -44,7 +44,7 @@ namespace model { return select; } - Poco::Data::Statement CryptoKeys::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement CryptoKey::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -56,7 +56,7 @@ namespace model { } - Poco::Data::Statement CryptoKeys::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement CryptoKey::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/CryptoKeys.h b/src/cpp/model/table/CryptoKey.h similarity index 92% rename from src/cpp/model/table/CryptoKeys.h rename to src/cpp/model/table/CryptoKey.h index 15991c70b..1a04dd387 100644 --- a/src/cpp/model/table/CryptoKeys.h +++ b/src/cpp/model/table/CryptoKey.h @@ -13,11 +13,11 @@ namespace model { KEY_TYPE_COUNT }; - class CryptoKeys : public ModelBase + class CryptoKey : public ModelBase { public: - CryptoKeys(); - ~CryptoKeys(); + CryptoKey(); + ~CryptoKey(); // generic db operations const char* getTableName() const { return "crypto_keys"; } diff --git a/src/cpp/model/table/Groups.cpp b/src/cpp/model/table/Group.cpp similarity index 73% rename from src/cpp/model/table/Groups.cpp rename to src/cpp/model/table/Group.cpp index e99780783..458f8f0dd 100644 --- a/src/cpp/model/table/Groups.cpp +++ b/src/cpp/model/table/Group.cpp @@ -1,19 +1,19 @@ -#include "Groups.h" +#include "Group.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - Groups::Groups() + Group::Group() { } - Groups::~Groups() + Group::~Group() { } - std::string Groups::toString() + std::string Group::toString() { std::stringstream ss; ss << "Alias: " << mAlias << std::endl; @@ -22,7 +22,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement Groups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement Group::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -32,7 +32,7 @@ namespace model { return select; } - Poco::Data::Statement Groups::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement Group::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -43,7 +43,7 @@ namespace model { return select; } - Poco::Data::Statement Groups::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement Group::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/Groups.h b/src/cpp/model/table/Group.h similarity index 91% rename from src/cpp/model/table/Groups.h rename to src/cpp/model/table/Group.h index adc5789c0..bde1b0d68 100644 --- a/src/cpp/model/table/Groups.h +++ b/src/cpp/model/table/Group.h @@ -6,11 +6,11 @@ namespace model { namespace table { - class Groups : public ModelBase + class Group : public ModelBase { public: - Groups(); - ~Groups(); + Group(); + ~Group(); // generic db operations const char* getTableName() const { return "groups"; } diff --git a/src/cpp/model/table/HederaAccounts.cpp b/src/cpp/model/table/HederaAccount.cpp similarity index 66% rename from src/cpp/model/table/HederaAccounts.cpp rename to src/cpp/model/table/HederaAccount.cpp index 3c019374d..4018c653a 100644 --- a/src/cpp/model/table/HederaAccounts.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -1,21 +1,21 @@ -#include "HederaAccounts.h" +#include "HederaAccount.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - HederaAccounts::HederaAccounts() + HederaAccount::HederaAccount() { } - HederaAccounts::~HederaAccounts() + HederaAccount::~HederaAccount() { } - std::string HederaAccounts::toString() + std::string HederaAccount::toString() { std::stringstream ss; ss << "user id: " << std::to_string(mUserId) << std::endl; @@ -28,7 +28,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement HederaAccounts::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -39,7 +39,16 @@ namespace model { return select; } - Poco::Data::Statement HederaAccounts::_loadIdFromDB(Poco::Data::Session session) + + Poco::Data::Statement HederaAccount::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + << " where " << fieldName << " LIKE ?"; + + return select; + } + Poco::Data::Statement HederaAccount::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -49,7 +58,7 @@ namespace model { unlock(); return select; } - Poco::Data::Statement HederaAccounts::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement HederaAccount::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); @@ -59,5 +68,7 @@ namespace model { unlock(); return insert; } + + } } \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccounts.h b/src/cpp/model/table/HederaAccount.h similarity index 72% rename from src/cpp/model/table/HederaAccounts.h rename to src/cpp/model/table/HederaAccount.h index 74b2063d4..c9c85b554 100644 --- a/src/cpp/model/table/HederaAccounts.h +++ b/src/cpp/model/table/HederaAccount.h @@ -2,15 +2,18 @@ #define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE #include "ModelBase.h" +#include "Poco/Tuple.h" namespace model { namespace table { - class HederaAccounts : public ModelBase + typedef Poco::Tuple HederaAccountsTuple; + + class HederaAccount : public ModelBase { public: - HederaAccounts(); - ~HederaAccounts(); + HederaAccount(); + ~HederaAccount(); // generic db operations const char* getTableName() const { return "hedera_accounts"; } @@ -19,6 +22,7 @@ namespace model { protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); diff --git a/src/cpp/model/table/HederaIds.cpp b/src/cpp/model/table/HederaId.cpp similarity index 74% rename from src/cpp/model/table/HederaIds.cpp rename to src/cpp/model/table/HederaId.cpp index 8eeed0e55..b048a0d71 100644 --- a/src/cpp/model/table/HederaIds.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -1,20 +1,20 @@ -#include "HederaIds.h" +#include "HederaId.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - HederaIds::HederaIds() + HederaId::HederaId() { } - HederaIds::~HederaIds() + HederaId::~HederaId() { } - std::string HederaIds::toString() + std::string HederaId::toString() { std::stringstream ss; ss << "Shard Num: " << std::to_string(mShardNum) << std::endl; @@ -23,7 +23,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement HederaIds::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -34,7 +34,7 @@ namespace model { return select; } - Poco::Data::Statement HederaIds::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement HederaId::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -44,7 +44,7 @@ namespace model { unlock(); return select; } - Poco::Data::Statement HederaIds::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement HederaId::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/HederaIds.h b/src/cpp/model/table/HederaId.h similarity index 91% rename from src/cpp/model/table/HederaIds.h rename to src/cpp/model/table/HederaId.h index eaa6612b8..ef35b2e70 100644 --- a/src/cpp/model/table/HederaIds.h +++ b/src/cpp/model/table/HederaId.h @@ -7,11 +7,11 @@ namespace model { namespace table { - class HederaIds : public ModelBase + class HederaId : public ModelBase { public: - HederaIds(); - ~HederaIds(); + HederaId(); + ~HederaId(); // generic db operations const char* getTableName() const { return "hedera_ids"; } diff --git a/src/cpp/model/table/HederaTopics.cpp b/src/cpp/model/table/HederaTopic.cpp similarity index 84% rename from src/cpp/model/table/HederaTopics.cpp rename to src/cpp/model/table/HederaTopic.cpp index aeed1ea05..ef80ea071 100644 --- a/src/cpp/model/table/HederaTopics.cpp +++ b/src/cpp/model/table/HederaTopic.cpp @@ -1,20 +1,20 @@ -#include "HederaTopics.h" +#include "HederaTopic.h" using namespace Poco::Data::Keywords; namespace model { namespace table { - HederaTopics::HederaTopics() + HederaTopic::HederaTopic() { } - HederaTopics::~HederaTopics() + HederaTopic::~HederaTopic() { } - std::string HederaTopics::toString() + std::string HederaTopic::toString() { std::stringstream ss; ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl; @@ -29,7 +29,7 @@ namespace model { return ss.str(); } - Poco::Data::Statement HederaTopics::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement HederaTopic::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -42,7 +42,7 @@ namespace model { return select; } - Poco::Data::Statement HederaTopics::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement HederaTopic::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); lock(); @@ -52,7 +52,7 @@ namespace model { unlock(); return select; } - Poco::Data::Statement HederaTopics::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement HederaTopic::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); lock(); diff --git a/src/cpp/model/table/HederaTopics.h b/src/cpp/model/table/HederaTopic.h similarity index 92% rename from src/cpp/model/table/HederaTopics.h rename to src/cpp/model/table/HederaTopic.h index 4584026ab..fe5cc342b 100644 --- a/src/cpp/model/table/HederaTopics.h +++ b/src/cpp/model/table/HederaTopic.h @@ -6,11 +6,11 @@ namespace model { namespace table { - class HederaTopics : public ModelBase + class HederaTopic : public ModelBase { public: - HederaTopics(); - ~HederaTopics(); + HederaTopic(); + ~HederaTopic(); // generic db operations const char* getTableName() const { return "hedera_topics"; } diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index e6f694c71..745982a25 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -315,7 +315,7 @@ namespace model { ss << "created: " << Poco::DateTimeFormatter::format(mCreated, "%f.%m.%Y %H:%M:%S") << "
    "; ss << "email checked: " << mEmailChecked << "
    "; ss << "language key: " << mLanguageKey << "
    "; - ss << "role: " << UserRoles::typeToString(getRole()) << "
    "; + ss << "role: " << UserRole::typeToString(getRole()) << "
    "; ss << "disabled: " << mDisabled << "
    "; mm->releaseMemory(pubkeyHex); @@ -357,7 +357,7 @@ namespace model { userObj.set("ident_hash", DRMakeStringHash(mEmail.data(), mEmail.size())); userObj.set("disabled", mDisabled); try { - userObj.set("role", UserRoles::typeToString(getRole())); + userObj.set("role", UserRole::typeToString(getRole())); } catch (Poco::Exception ex) { addError(new ParamError("User::getJson", "exception by getting role", ex.displayText().data())); diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index 50908b049..3a6164232 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -11,7 +11,7 @@ #include -#include "UserRoles.h" +#include "UserRole.h" namespace model { namespace table { diff --git a/src/cpp/model/table/UserBackups.cpp b/src/cpp/model/table/UserBackup.cpp similarity index 78% rename from src/cpp/model/table/UserBackups.cpp rename to src/cpp/model/table/UserBackup.cpp index 0dbf0adfa..e45a78066 100644 --- a/src/cpp/model/table/UserBackups.cpp +++ b/src/cpp/model/table/UserBackup.cpp @@ -1,4 +1,4 @@ -#include "UserBackups.h" +#include "UserBackup.h" #include "../../controller/User.h" using namespace Poco::Data::Keywords; @@ -6,31 +6,31 @@ using namespace Poco::Data::Keywords; namespace model { namespace table { - UserBackups::UserBackups() + UserBackup::UserBackup() : mUserId(0), mMnemonicType(0) { detectMnemonic(); } - UserBackups::UserBackups(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) + UserBackup::UserBackup(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type) : mUserId(user_id), mPassphrase(passphrase), mMnemonicType(type) { detectMnemonic(); } - UserBackups::UserBackups(const UserBackupsTuple& tuple) + UserBackup::UserBackup(const UserBackupsTuple& tuple) : ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mPassphrase(tuple.get<2>()), mMnemonicType(tuple.get<3>()) { detectMnemonic(); } - UserBackups::~UserBackups() + UserBackup::~UserBackup() { } - Poco::Data::Statement UserBackups::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement UserBackup::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); @@ -43,7 +43,7 @@ namespace model { } - Poco::Data::Statement UserBackups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserBackup::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -55,7 +55,7 @@ namespace model { return select; } - Poco::Data::Statement UserBackups::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement UserBackup::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); @@ -66,7 +66,7 @@ namespace model { return select; } - Poco::Data::Statement UserBackups::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserBackup::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -77,7 +77,7 @@ namespace model { return select; } - Poco::Data::Statement UserBackups::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) + Poco::Data::Statement UserBackup::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) { Poco::Data::Statement select(session); if (fieldNames.size() <= 1) { @@ -107,7 +107,7 @@ namespace model { } // generic db operations - std::string UserBackups::toString() + std::string UserBackup::toString() { std::stringstream ss; ss << "user_id: " << mUserId << std::endl; @@ -116,7 +116,7 @@ namespace model { return ss.str(); } - void UserBackups::detectMnemonic() + void UserBackup::detectMnemonic() { if (mMnemonicType == -1) { const static char* function_name = "UserBackups::detectMnemonic"; diff --git a/src/cpp/model/table/UserBackups.h b/src/cpp/model/table/UserBackup.h similarity index 88% rename from src/cpp/model/table/UserBackups.h rename to src/cpp/model/table/UserBackup.h index d307f8f5d..c5084b0f7 100644 --- a/src/cpp/model/table/UserBackups.h +++ b/src/cpp/model/table/UserBackup.h @@ -9,13 +9,13 @@ namespace model { typedef Poco::Tuple UserBackupsTuple; - class UserBackups : public ModelBase + class UserBackup : public ModelBase { public: - UserBackups(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); - UserBackups(const UserBackupsTuple& tuple); - UserBackups(); - ~UserBackups(); + UserBackup(int user_id, const std::string& passphrase, ServerConfig::Mnemonic_Types type); + UserBackup(const UserBackupsTuple& tuple); + UserBackup(); + ~UserBackup(); // generic db operations const char* getTableName() const { return "user_backups"; } diff --git a/src/cpp/model/table/UserRoles.cpp b/src/cpp/model/table/UserRole.cpp similarity index 73% rename from src/cpp/model/table/UserRoles.cpp rename to src/cpp/model/table/UserRole.cpp index 0d1f673e9..28e314606 100644 --- a/src/cpp/model/table/UserRoles.cpp +++ b/src/cpp/model/table/UserRole.cpp @@ -1,4 +1,4 @@ -#include "UserRoles.h" +#include "UserRole.h" using namespace Poco::Data::Keywords; @@ -6,28 +6,28 @@ namespace model { namespace table { - UserRoles::UserRoles(int user_id, RoleType type) + UserRole::UserRole(int user_id, RoleType type) : mUserId(user_id), mType(type) { } - UserRoles::UserRoles(const UserRolesTuple& tuple) + UserRole::UserRole(const UserRolesTuple& tuple) : ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mType(tuple.get<2>()) { } - UserRoles::UserRoles() + UserRole::UserRole() { } - UserRoles::~UserRoles() + UserRole::~UserRole() { } - Poco::Data::Statement UserRoles::_insertIntoDB(Poco::Data::Session session) + Poco::Data::Statement UserRole::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); @@ -40,7 +40,7 @@ namespace model { } - Poco::Data::Statement UserRoles::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserRole::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -52,7 +52,7 @@ namespace model { return select; } - Poco::Data::Statement UserRoles::_loadIdFromDB(Poco::Data::Session session) + Poco::Data::Statement UserRole::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); @@ -63,7 +63,7 @@ namespace model { return select; } - Poco::Data::Statement UserRoles::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + Poco::Data::Statement UserRole::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -74,7 +74,7 @@ namespace model { return select; } - Poco::Data::Statement UserRoles::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) + Poco::Data::Statement UserRole::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) { Poco::Data::Statement select(session); if (fieldNames.size() <= 1) { @@ -104,7 +104,7 @@ namespace model { } // generic db operations - std::string UserRoles::toString() + std::string UserRole::toString() { std::stringstream ss; ss << "user_id: " << mUserId << std::endl; @@ -112,7 +112,7 @@ namespace model { return ss.str(); } - const char* UserRoles::typeToString(RoleType type) + const char* UserRole::typeToString(RoleType type) { switch (type) { case ROLE_NOT_LOADED: return "not loaded"; diff --git a/src/cpp/model/table/UserRoles.h b/src/cpp/model/table/UserRole.h similarity index 90% rename from src/cpp/model/table/UserRoles.h rename to src/cpp/model/table/UserRole.h index 7b3fad790..7683bff94 100644 --- a/src/cpp/model/table/UserRoles.h +++ b/src/cpp/model/table/UserRole.h @@ -17,13 +17,13 @@ namespace model { typedef Poco::Tuple UserRolesTuple; - class UserRoles : public ModelBase + class UserRole : public ModelBase { public: - UserRoles(int user_id, RoleType type); - UserRoles(const UserRolesTuple& tuple); - UserRoles(); - ~UserRoles(); + UserRole(int user_id, RoleType type); + UserRole(const UserRolesTuple& tuple); + UserRole(); + ~UserRole(); // generic db operations const char* getTableName() const { return "user_roles"; } diff --git a/src/cpsp/adminCheckUserBackup.cpsp b/src/cpsp/adminCheckUserBackup.cpsp index bca35b05a..35ac38ad4 100644 --- a/src/cpsp/adminCheckUserBackup.cpsp +++ b/src/cpsp/adminCheckUserBackup.cpsp @@ -18,7 +18,7 @@ typedef Poco::Tuple, std::string> UserBack struct SListEntry { Poco::AutoPtr user; - std::vector> backups; + std::vector> backups; }; %> @@ -73,7 +73,7 @@ struct SListEntry SListEntry entry; entry.user = controller::User::create(); entry.user->load(user_id); - entry.backups = controller::UserBackups::load(user_id); + entry.backups = controller::UserBackup::load(user_id); notMatchingEntrys.push_back(entry); diff --git a/src/cpsp/adminUserPasswordReset.cpsp b/src/cpsp/adminUserPasswordReset.cpsp index 648a18f61..f534b8c4d 100644 --- a/src/cpsp/adminUserPasswordReset.cpsp +++ b/src/cpsp/adminUserPasswordReset.cpsp @@ -21,7 +21,7 @@ enum PageState PageState state = PAGE_ASK_EMAIL; Poco::AutoPtr user = controller::User::create(); Poco::AutoPtr code; - Poco::AutoPtr userBackup; + Poco::AutoPtr userBackup; bool validUser = false; std::string pageName = "Admin User Passwort Reset"; diff --git a/src/cpsp/repairDefectPassphrase.cpsp b/src/cpsp/repairDefectPassphrase.cpsp index fc9eba7fd..0e8c82e64 100644 --- a/src/cpsp/repairDefectPassphrase.cpsp +++ b/src/cpsp/repairDefectPassphrase.cpsp @@ -64,7 +64,7 @@ enum PageState else { mSession->setPassphrase(passphrase); - auto newPassphraseModel = controller::UserBackups::create( + auto newPassphraseModel = controller::UserBackup::create( user_model->getID(), passphrase->getString(), ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES From cb86ed9422f501c3484321dbf8b8008557e3faf2 Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 27 Aug 2020 08:35:18 +0200 Subject: [PATCH 057/195] add groups page for listing and add groups (only for admins) --- skeema/gradido_login/groups.sql | 1 + skeema/gradido_login/hedera_topics.sql | 2 +- src/cpp/HTTPInterface/AdminGroupsPage.cpp | 212 ++++++++++++++++++ src/cpp/HTTPInterface/AdminGroupsPage.h | 20 ++ .../PageRequestHandlerFactory.cpp | 6 + src/cpp/controller/Group.cpp | 69 ++++++ src/cpp/controller/Group.h | 33 +++ src/cpp/model/table/Group.cpp | 41 +++- src/cpp/model/table/Group.h | 19 +- src/cpp/model/table/ModelBase.cpp | 7 + src/cpp/model/table/ModelBase.h | 26 +++ src/cpsp/adminGroups.cpsp | 80 +++++++ 12 files changed, 510 insertions(+), 6 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminGroupsPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminGroupsPage.h create mode 100644 src/cpp/controller/Group.cpp create mode 100644 src/cpp/controller/Group.h create mode 100644 src/cpsp/adminGroups.cpsp diff --git a/skeema/gradido_login/groups.sql b/skeema/gradido_login/groups.sql index 8c5e143bb..7d4c5a185 100644 --- a/skeema/gradido_login/groups.sql +++ b/skeema/gradido_login/groups.sql @@ -2,6 +2,7 @@ CREATE TABLE `groups` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `alias` varchar(190) NOT NULL, `name` varchar(255) NOT NULL, + `url` varchar(255) NOT NULL, `description` text, PRIMARY KEY (`id`), UNIQUE KEY `alias` (`alias`) diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index 6a58174c1..02f7e3b39 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -6,7 +6,7 @@ CREATE TABLE `hedera_topics` ( `group_id` int unsigned NOT NULL, `admin_key_id` int unsigned DEFAULT NULL, `submit_key_id` int unsigned DEFAULT NULL, - `current_timeout` timestamp NOT NULL DEFAULT '0', + `current_timeout` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', `sequence_number` bigint unsigned DEFAULT '0', `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), diff --git a/src/cpp/HTTPInterface/AdminGroupsPage.cpp b/src/cpp/HTTPInterface/AdminGroupsPage.cpp new file mode 100644 index 000000000..1e6619801 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminGroupsPage.cpp @@ -0,0 +1,212 @@ +#include "AdminGroupsPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + + #include "../controller/Group.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + +#include "../ServerConfig.h" + + +AdminGroupsPage::AdminGroupsPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + + const char* pageName = "Gruppen"; + + // add + if(!form.empty()) { + auto alias = form.get("group-alias"); + if(alias == "") + { + addError(new Error("Add Group", "Alias is empty!")); + } + else + { + auto newGroup = controller::Group::create( + alias, + form.get("group-name", ""), + form.get("group-url", ""), + form.get("group-desc", "") + ); + newGroup->getModel()->insertIntoDB(false); + } + } + + // select all + auto groups = controller::Group::listAll(); + //auto groups = controller::Group::load("gdd1"); + //std::vector> groups; + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; + // end include header.cpsp + responseStream << "\n"; +#line 38 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t

    Alle Gruppen

    \n"; + responseStream << "\t\t
    \t\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t
    ID
    \n"; + responseStream << "\t\t\t\t
    Name
    \n"; + responseStream << "\t\t\t\t
    Alias
    \n"; + responseStream << "\t\t\t\t
    Url
    \n"; + responseStream << "\t\t\t\t
    "; +#line 50 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( gettext("Description") ); + responseStream << "
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 52 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getID() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getName() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 57 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getAlias() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 58 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getUrl() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + responseStream << ( group_model->getDescription()); + responseStream << "
    \n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 61 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" + } responseStream << "\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t

    Eine neue Gruppe anlegen

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t
    \n"; + responseStream << "
    \n"; + // begin include footer.cpsp + responseStream << "
    \n"; + responseStream << "

    Copyright © Gradido 2020

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "

    Login Server in Entwicklung

    \n"; + responseStream << "

    Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminGroupsPage.h b/src/cpp/HTTPInterface/AdminGroupsPage.h new file mode 100644 index 000000000..43a99ffb4 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminGroupsPage.h @@ -0,0 +1,20 @@ +#ifndef AdminGroupsPage_INCLUDED +#define AdminGroupsPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminGroupsPage: public SessionHTTPRequestHandler +{ +public: + AdminGroupsPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminGroupsPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 454cc930a..50dc610af 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -27,6 +27,7 @@ #include "PassphrasedTransaction.h" #include "AdminUserPasswordReset.h" #include "RegisterDirectPage.h" +#include "AdminGroupsPage.h" #include "DecodeTransactionPage.h" #include "RepairDefectPassphrase.h" @@ -206,6 +207,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/groups") { + auto pageRequestHandler = new AdminGroupsPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/controller/Group.cpp b/src/cpp/controller/Group.cpp new file mode 100644 index 000000000..d5b3eb2ba --- /dev/null +++ b/src/cpp/controller/Group.cpp @@ -0,0 +1,69 @@ + +#include "Group.h" + +namespace controller { + + Group::Group(model::table::Group* dbModel) + { + mDBModel = dbModel; + } + + Group::~Group() + { + + } + + Poco::AutoPtr Group::create(const std::string& alias, const std::string& name, const std::string& url, const std::string& description) + { + auto db = new model::table::Group(alias, name, url, description); + auto group = new Group(db); + return Poco::AutoPtr(group); + } + + std::vector> Group::load(const std::string& alias) + { + auto db = new model::table::Group(); + auto group_list = db->loadFromDB("alias", alias, 0); + + std::vector> resultVector; + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + resultVector.push_back(new Group(new model::table::Group(*it))); + } + return resultVector; + } + + std::vector> Group::listAll() + { + auto db = new model::table::Group(); + std::vector group_list; + // throw an unresolved external symbol error + //group_list = db->loadAllFromDB(); + + // work around for not working call to loadAllFromDB + auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + + select << "SELECT id, alias, name, url, description FROM " << db->getTableName() + , Poco::Data::Keywords::into(group_list); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + } + catch (Poco::Exception& ex) { + printf("[Group::listAll] poco exception: %s\n", ex.displayText().data()); + } + // work around end + std::vector> resultVector; + + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + Poco::AutoPtr group_ptr(new Group(new model::table::Group(*it))); + resultVector.push_back(group_ptr); + } + return resultVector; + } + +} + diff --git a/src/cpp/controller/Group.h b/src/cpp/controller/Group.h new file mode 100644 index 000000000..e1ff29b64 --- /dev/null +++ b/src/cpp/controller/Group.h @@ -0,0 +1,33 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_GROUP_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_GROUP_INCLUDE + +#include "../model/table/Group.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + class Group : public TableControllerBase + { + public: + + ~Group(); + + static Poco::AutoPtr create(const std::string& alias, const std::string& name, const std::string& url, const std::string& description); + + static std::vector> load(const std::string& alias); + static std::vector> listAll(); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + Group(model::table::Group* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_GROUP_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/Group.cpp b/src/cpp/model/table/Group.cpp index 458f8f0dd..c1a84e832 100644 --- a/src/cpp/model/table/Group.cpp +++ b/src/cpp/model/table/Group.cpp @@ -8,6 +8,19 @@ namespace model { { } + Group::Group(const std::string& alias, const std::string& name, const std::string& url, const std::string& description) + : mAlias(alias), mName(name), mUrl(url), mDescription(description) + { + + } + + Group::Group(GroupTuple tuple) + : ModelBase(tuple.get<0>()), + mAlias(tuple.get<1>()), mName(tuple.get<2>()), mUrl(tuple.get<3>()), mDescription(tuple.get<4>()) + { + + } + Group::~Group() { @@ -18,6 +31,7 @@ namespace model { std::stringstream ss; ss << "Alias: " << mAlias << std::endl; ss << "Name: " << mName << std::endl; + ss << "Url: " << mUrl << std::endl; ss << "Description:" << mDescription << std::endl; return ss.str(); } @@ -26,9 +40,28 @@ namespace model { { Poco::Data::Statement select(session); - select << "SELECT id, alias, name, description FROM " << getTableName() + select << "SELECT id, alias, name, url, description FROM " << getTableName() << " where " << fieldName << " = ?" - , into(mID), into(mAlias), into(mName), into(mDescription); + , into(mID), into(mAlias), into(mName), into(mUrl), into(mDescription); + + return select; + } + + Poco::Data::Statement Group::_loadAllFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + + select << "SELECT id, alias, name, url, description FROM " << getTableName(); + + return select; + } + + Poco::Data::Statement Group::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + // typedef Poco::Tuple, int> UserTuple; + select << "SELECT id, alias, name, url, description FROM " << getTableName() + << " where " << fieldName << " LIKE ?"; return select; } @@ -48,8 +81,8 @@ namespace model { Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (alias, name, description) VALUES(?,?,?)" - , use(mAlias), use(mName), use(mDescription); + << " (alias, name, url, description) VALUES(?,?,?,?)" + , use(mAlias), use(mName), use(mUrl), use(mDescription); unlock(); return insert; } diff --git a/src/cpp/model/table/Group.h b/src/cpp/model/table/Group.h index bde1b0d68..1f6296b92 100644 --- a/src/cpp/model/table/Group.h +++ b/src/cpp/model/table/Group.h @@ -2,30 +2,47 @@ #define GRADIDO_LOGIN_SERVER_MODEL_TABLE_GROUPS_INCLUDE #include "ModelBase.h" +#include "Poco/Tuple.h" namespace model { namespace table { + typedef Poco::Tuple GroupTuple; + class Group : public ModelBase { public: Group(); + Group(const std::string& alias, const std::string& name, const std::string& url, const std::string& description); + Group(GroupTuple userTuple); ~Group(); // generic db operations const char* getTableName() const { return "groups"; } std::string toString(); + inline const std::string& getAlias() const { return mAlias; } + inline const std::string& getName() const { std::shared_lock _lock(mSharedMutex); return mName; } + inline const std::string& getDescription() const { std::shared_lock _lock(mSharedMutex); return mDescription; } + inline const std::string& getUrl() const { std::shared_lock _lock(mSharedMutex); return mUrl; } + + inline void setName(const std::string& name) { std::unique_lock _lock(mSharedMutex); mName = name; } + inline void setDescription(const std::string& desc) { std::unique_lock _lock(mSharedMutex); mDescription = desc; } + inline void setUrl(const std::string& url) { std::unique_lock _lock(mSharedMutex); mUrl = url; } protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadAllFromDB(Poco::Data::Session session); + Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); - + std::string mAlias; std::string mName; + std::string mUrl; std::string mDescription; + mutable std::shared_mutex mSharedMutex; }; } diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index ad64a4e54..5dfb709fb 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -138,6 +138,13 @@ namespace model { throw Poco::Exception(message); } + Poco::Data::Statement ModelBase::_loadAllFromDB(Poco::Data::Session session) + { + std::string message = getTableName(); + message += "::_loadAllFromDB not implemented"; + throw Poco::Exception(message); + } + Poco::DateTime ModelBase::parseElopageDate(std::string dateString) { std::string decodedDateString = ""; diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 3d3bc3ab8..2ec7a3ee2 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -42,6 +42,8 @@ namespace model { bool isExistInDB(const std::string& fieldName, const T& fieldValue); template std::vector loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0); + template + std::vector loadAllFromDB(); template size_t loadFromDB(const std::vector& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType = MYSQL_CONDITION_AND); template @@ -62,6 +64,7 @@ namespace model { virtual Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session) = 0; virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName) = 0; virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND); + virtual Poco::Data::Statement _loadAllFromDB(Poco::Data::Session session); virtual Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); virtual Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::vector fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND); virtual Poco::Data::Statement _insertIntoDB(Poco::Data::Session session) = 0; @@ -147,6 +150,29 @@ namespace model { return results; } + template + std::vector loadAllFromDB() + { + std::vector results; + Poco::ScopedLock _lock(mWorkMutex); + + auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select = _loadAllFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + select, Poco::Data::Keywords::into(results); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + } + catch (Poco::Exception& ex) { + lock(); + addError(new ParamError(getTableName(), "mysql error by selecting all", ex.displayText().data())); + unlock(); + } + + return results; + } + template std::vector ModelBase::loadFromDB(const std::vector& fieldNames, const std::vector& fieldValues, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/, int expectedResults/* = 0*/) { diff --git a/src/cpsp/adminGroups.cpsp b/src/cpsp/adminGroups.cpsp new file mode 100644 index 000000000..e357388af --- /dev/null +++ b/src/cpsp/adminGroups.cpsp @@ -0,0 +1,80 @@ +<%@ page class="AdminGroupsPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + #include "../controller/Group.h" +%> +<%% + const char* pageName = "Gruppen"; + + // add + if(!form.empty()) { + auto alias = form.get("group-alias"); + if(alias == "") + { + addError(new Error("Add Group", "Alias is empty!")); + } + else + { + auto newGroup = controller::Group::create( + alias, + form.get("group-name", ""), + form.get("group-url", ""), + form.get("group-desc", "") + ); + newGroup->getModel()->insertIntoDB(false); + } + } + + // select all + auto groups = controller::Group::listAll(); + //auto groups = controller::Group::load("gdd1"); + //std::vector> groups; + +%><%@ include file="header.cpsp" %> +<%= getErrorsHtml() %> +
    +
    +
    +

    Alle Gruppen

    +
    +
    +
    +
    ID
    +
    Name
    +
    Alias
    +
    Url
    +
    <%= gettext("Description") %>
    +
    + <% for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); %> +
    +
    <%= group_model->getID() %>
    +
    <%= group_model->getName() %>
    +
    <%= group_model->getAlias() %>
    +
    <%= group_model->getUrl() %>
    +
    <%= group_model->getDescription()%>
    +
    + <% } %> +
    +
    +
    +

    Eine neue Gruppe anlegen

    +
    +
    +
    + + + + + + + + + "> +
    +
    +<%@ include file="footer.cpsp" %> From ba23cf7e3768b81c679cbdeef31b4d06f0b07062 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:33:11 +0200 Subject: [PATCH 058/195] add KeyPairHedera mostly copied from KeyPairEd25519 but not testet yet. Maybe I must use the iroha ed25519 implementation because in the past sodium don't work together with hedera --- src/cpp/Crypto/KeyPairHedera.cpp | 148 +++++++++++++++++++++++++++++++ src/cpp/Crypto/KeyPairHedera.h | 82 +++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 src/cpp/Crypto/KeyPairHedera.cpp create mode 100644 src/cpp/Crypto/KeyPairHedera.h diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp new file mode 100644 index 000000000..80c4649b1 --- /dev/null +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -0,0 +1,148 @@ +#include "KeyPairHedera.h" +#include "../lib/DataTypeConverter.h" +#include + +#include "../SingletonManager/ErrorManager.h" + +KeyPairHedera::KeyPairHedera() + : mPrivateKey(nullptr) +{ + +} + + +KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) + : mPrivateKey(nullptr) +{ + auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420"); + auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100"); + + auto mm = MemoryManager::getInstance(); + + if (privateKey) { + switch (privateKey->size()) { + case 48: + // key with prefix + if (0 == sodium_memcmp(*privateKey, *derPrefixPriv, derPrefixPriv->size())) { + //int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed); + auto seed = mm->getFreeMemory(crypto_sign_ed25519_SEEDBYTES); + memcpy(*seed, privateKey->data(derPrefixPriv->size()), crypto_sign_ed25519_SEEDBYTES); + createKeyFromSeed(seed); + break; + } + case 32: + createKeyFromSeed(privateKey); + break; + case 64: + //mPrivateKey = privateKey; + if (!mPrivateKey || mPrivateKey->size() != privateKey->size()) { + if (mPrivateKey) { + mm->releaseMemory(mPrivateKey); + } + mPrivateKey = mm->getFreeMemory(privateKey->size()); + memcpy(*mPrivateKey, *privateKey, privateKey->size()); + } + break; + default: + throw std::exception("[KeyPairHedera] invalid private key"); + } + crypto_sign_ed25519_sk_to_pk(mPublicKey, *mPrivateKey); + } + else if (publicKey) { + switch (publicKey->size()) + { + case 32: { // raw public key + memcpy(mPublicKey, *publicKey, publicKey->size()); + break; + } + case 44: // DER encoded public key + if (0 == sodium_memcmp(*publicKey, *derPrefixPub, derPrefixPub->size())) { + memcpy(mPublicKey, publicKey->data(derPrefixPub->size()), ed25519_pubkey_SIZE); + } + break; + default: + throw std::exception("[KeyPairHedera] invalid public key"); + } + } + + + mm->releaseMemory(derPrefixPriv); + mm->releaseMemory(derPrefixPub); +} + +KeyPairHedera::~KeyPairHedera() +{ + auto mm = MemoryManager::getInstance(); + if (mPrivateKey) { + mm->releaseMemory(mPrivateKey); + mPrivateKey = nullptr; + } +} + + +void KeyPairHedera::createKeyFromSeed(const MemoryBin* seed) +{ + assert(seed && seed->size() == crypto_sign_ed25519_SEEDBYTES); + + auto mm = MemoryManager::getInstance(); + auto secret_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES); + crypto_sign_seed_keypair(mPublicKey, *secret_key, *seed); + + if (mPrivateKey) { + mm->releaseMemory(mPrivateKey); + } + mPrivateKey = secret_key; + + // iroha + //ed25519_privkey_SIZE + //ed25519_derive_public_key(const private_key_t* sk,public_key_t* pk); +} + +MemoryBin* KeyPairHedera::sign(const unsigned char* message, size_t messageSize) const +{ + if (!message || !messageSize) return nullptr; + if (!mPrivateKey) return nullptr; + auto mm = MemoryManager::getInstance(); + auto em = ErrorManager::getInstance(); + + const static char functionName[] = "KeyPairHedera::sign"; + + auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES); + unsigned long long actualSignLength = 0; + + if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *mPrivateKey)) { + em->addError(new Error(functionName, "sign failed")); + auto messageHex = DataTypeConverter::binToHex(message, messageSize); + em->addError(new ParamError(functionName, "message as hex", messageHex)); + mm->releaseMemory(signBinBuffer); + return nullptr; + } + + if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) { + // Incorrect signature! + //printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__); + em->addError(new Error(functionName, "sign verify failed")); + auto messageHex = DataTypeConverter::binToHex(message, messageSize); + em->addError(new ParamError(functionName, "message as hex", messageHex)); + mm->releaseMemory(signBinBuffer); + return nullptr; + } + + // debug + /*const size_t hex_sig_size = crypto_sign_BYTES * 2 + 1; + char sig_hex[hex_sig_size]; + sodium_bin2hex(sig_hex, hex_sig_size, *signBinBuffer, crypto_sign_BYTES); + printf("[User::sign] signature hex: %s\n", sig_hex); + */ + + return signBinBuffer; + +} + +bool KeyPairHedera::verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const +{ + if (crypto_sign_verify_detached(*signature, message, messageSize, mPublicKey) != 0) { + return false; + } + return true; +} \ No newline at end of file diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h new file mode 100644 index 000000000..358a3b680 --- /dev/null +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -0,0 +1,82 @@ +#ifndef __GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H +#define __GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H + +#include "IKeyPair.h" + +/*! +* \author: Dario Rekowski +* +* \date: 2020-08-28 +* +* \brief: Key Pairs class for ed25519 keys, used by hedera for transaction sign +*/ + + +#include "sodium.h" +#include "iroha-ed25519/include/ed25519/ed25519.h" + +class KeyPairHedera : public IKeyPair +{ +public: + //! \param privateKey: copy + //! \param publicKey: copy + //! + KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); + + ~KeyPairHedera(); + + + //! \return caller take ownership of return value + MemoryBin* sign(const MemoryBin* message) const { return sign(message->data(), message->size()); } + inline MemoryBin* sign(const std::string& bodyBytes) const { return sign((const unsigned char*)bodyBytes.data(), bodyBytes.size()); } + MemoryBin* sign(const unsigned char* message, size_t messageSize) const; + + bool verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const; + + inline const unsigned char* getPublicKey() const { return mPublicKey; } + + inline bool isTheSame(const KeyPairHedera& b) const { + return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); + } + inline bool isTheSame(const unsigned char* pubkey) const { + if (!pubkey) + return false; + return 0 == sodium_memcmp(mPublicKey, pubkey, ed25519_pubkey_SIZE); + } + //! \return 0 if the same + //! \return -1 if not the same + //! \return 1 if hasn't private key + inline int isTheSame(const MemoryBin* privkey) const { + if (!mPrivateKey) return 1; + if (privkey->size() != mPrivateKey->size()) return -1; + return sodium_memcmp(*mPrivateKey, *privkey, privkey->size()); + } + + inline bool operator == (const KeyPairHedera& b) const { return isTheSame(b); } + inline bool operator != (const KeyPairHedera& b) const { return !isTheSame(b); } + + inline bool operator == (const unsigned char* b) const { return isTheSame(b); } + inline bool operator != (const unsigned char* b) const { return !isTheSame(b); } + + inline bool hasPrivateKey() const { return mPrivateKey != nullptr; } + + + +protected: + + KeyPairHedera(); + void createKeyFromSeed(const MemoryBin* seed); + +private: + // 64 Byte + //! \brief ed25519 libsodium private key + //! + //! TODO: replace MemoryBin by a memory obfuscation class which make it hard to steal the private key from memory + MemoryBin* mPrivateKey; + + // 32 Byte + //! \brief ed25519 libsodium public key + unsigned char mPublicKey[ed25519_pubkey_SIZE]; +}; + +#endif //__GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H \ No newline at end of file From 5575208cacceff363dbf7e0a7728f584987bac96 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:34:33 +0200 Subject: [PATCH 059/195] update comments, answer question --- src/cpp/Crypto/KeyPairEd25519.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpp/Crypto/KeyPairEd25519.h b/src/cpp/Crypto/KeyPairEd25519.h index 75a1ce9f1..08da7030d 100644 --- a/src/cpp/Crypto/KeyPairEd25519.h +++ b/src/cpp/Crypto/KeyPairEd25519.h @@ -9,6 +9,7 @@ * \date: 2020-06-04 * * \brief: Key Pairs class for ed25519 keys, used for default gradido transactions + * TODO: add verify method */ @@ -75,6 +76,9 @@ private: //! \brief ed25519 libsodium private key //! //! Why it is a pointer and the public is an array? + //! Because MemoryBin should be replaced by a memory obfuscation class which make it harder to steal the private key from computer memory + //! And because private key can be nullptr for example to verify a signed message + //! TODO: replace MemoryBin by a memory obfuscation class which make it hard to steal the private key from memory MemoryBin* mSodiumSecret; From d285287be54fb4d0c05f29f779c40d1e6331637c Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:36:02 +0200 Subject: [PATCH 060/195] extend memory bin to get access of part of data, for example copy the last half of it --- src/cpp/SingletonManager/MemoryManager.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpp/SingletonManager/MemoryManager.h b/src/cpp/SingletonManager/MemoryManager.h index 7cb9233f7..591148083 100644 --- a/src/cpp/SingletonManager/MemoryManager.h +++ b/src/cpp/SingletonManager/MemoryManager.h @@ -18,6 +18,7 @@ #include #include +#include #define MEMORY_MANAGER_PAGE_SIZE 10 @@ -41,6 +42,8 @@ public: inline unsigned char* data() { return mData; } inline const unsigned char* data() const { return mData; } + inline unsigned char* data(size_t startIndex) { assert(startIndex < mSize); return &mData[startIndex]; } + inline const unsigned char* data(size_t startIndex) const { assert(startIndex < mSize); return &mData[startIndex]; } std::string convertToHex(); //! \return 0 if ok //! -1 if bin is to small From 71837dbe61091ae4a856073f0fe2df3d8e650c5a Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 12:37:13 +0200 Subject: [PATCH 061/195] Add hedera account page files and classes needed for this --- .../HTTPInterface/AdminHederaAccountPage.cpp | 125 ++++++++++++++++++ .../HTTPInterface/AdminHederaAccountPage.h | 20 +++ .../PageRequestHandlerFactory.cpp | 12 ++ src/cpp/controller/HederaAccount.cpp | 69 ++++++++++ src/cpp/controller/HederaAccount.h | 33 +++++ src/cpp/model/table/CryptoKey.h | 4 +- src/cpp/model/table/HederaAccount.cpp | 14 ++ src/cpp/model/table/HederaAccount.h | 4 +- src/cpsp/adminTopic.cpsp | 23 ++++ src/cpsp/header_large.cpsp | 19 +++ 10 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminHederaAccountPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminHederaAccountPage.h create mode 100644 src/cpp/controller/HederaAccount.cpp create mode 100644 src/cpp/controller/HederaAccount.h create mode 100644 src/cpsp/adminTopic.cpsp create mode 100644 src/cpsp/header_large.cpsp diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp new file mode 100644 index 000000000..0500a8996 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -0,0 +1,125 @@ +#include "AdminHederaAccountPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + + #include "../controller/HederaAccount.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +AdminHederaAccountPage::AdminHederaAccountPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + + const char* pageName = "Hedera Account"; + + // add + if(!form.empty()) { + + } + + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t\t
    "; + // end include header_large.cpsp + responseStream << "\n"; +#line 21 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t

    Einen neuen Account anlegen

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t
    \n"; + responseStream << "
    \n"; + // begin include footer.cpsp + responseStream << "
    \n"; + responseStream << "

    Copyright © Gradido 2020

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "

    Login Server in Entwicklung

    \n"; + responseStream << "

    Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.h b/src/cpp/HTTPInterface/AdminHederaAccountPage.h new file mode 100644 index 000000000..b35f6ffb3 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.h @@ -0,0 +1,20 @@ +#ifndef AdminHederaAccountPage_INCLUDED +#define AdminHederaAccountPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminHederaAccountPage: public SessionHTTPRequestHandler +{ +public: + AdminHederaAccountPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminHederaAccountPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 50dc610af..11cdb7d78 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -28,6 +28,8 @@ #include "AdminUserPasswordReset.h" #include "RegisterDirectPage.h" #include "AdminGroupsPage.h" +#include "AdminTopicPage.h" +#include "AdminHederaAccountPage.h" #include "DecodeTransactionPage.h" #include "RepairDefectPassphrase.h" @@ -212,6 +214,16 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/topic") { + auto pageRequestHandler = new AdminTopicPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } + if (url_first_part == "/hedera_account") { + auto pageRequestHandler = new AdminHederaAccountPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp new file mode 100644 index 000000000..9a858bd7c --- /dev/null +++ b/src/cpp/controller/HederaAccount.cpp @@ -0,0 +1,69 @@ + +#include "HederaAccount.h" + +namespace controller { + + HederaAccount::HederaAccount(model::table::HederaAccount* dbModel) + { + mDBModel = dbModel; + } + + HederaAccount::~HederaAccount() + { + + } + + Poco::AutoPtr HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) + { + auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance); + auto group = new HederaAccount(db); + return Poco::AutoPtr(group); + } + + std::vector> HederaAccount::load(const std::string& alias) + { + auto db = new model::table::HederaAccount(); + auto group_list = db->loadFromDB("alias", alias, 0); + + std::vector> resultVector; + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + resultVector.push_back(new HederaAccount(new model::table::HederaAccount(*it))); + } + return resultVector; + } + + std::vector> HederaAccount::listAll() + { + auto db = new model::table::HederaAccount(); + std::vector group_list; + // throw an unresolved external symbol error + //group_list = db->loadAllFromDB(); + + // work around for not working call to loadAllFromDB + auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + + select << "SELECT id, alias, name, url, description FROM " << db->getTableName() + , Poco::Data::Keywords::into(group_list); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + } + catch (Poco::Exception& ex) { + printf("[Group::listAll] poco exception: %s\n", ex.displayText().data()); + } + // work around end + std::vector> resultVector; + + resultVector.reserve(group_list.size()); + for (auto it = group_list.begin(); it != group_list.end(); it++) { + Poco::AutoPtr group_ptr(new HederaAccount(new model::table::HederaAccount(*it))); + resultVector.push_back(group_ptr); + } + return resultVector; + } + +} + diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h new file mode 100644 index 000000000..9efd89c12 --- /dev/null +++ b/src/cpp/controller/HederaAccount.h @@ -0,0 +1,33 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE + +#include "../model/table/HederaAccount.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + class HederaAccount : public TableControllerBase + { + public: + + ~HederaAccount(); + + static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + + static std::vector> load(const std::string& alias); + static std::vector> listAll(); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + HederaAccount(model::table::HederaAccount* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index 1a04dd387..f4fd8bebf 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -8,8 +8,8 @@ namespace model { namespace table { enum KeyType { - KEY_TYPE_SODIUM_ED25519, - KEY_TYPE_ED25519_REF10, + KEY_TYPE_SODIUM_ED25519 = 0, + KEY_TYPE_ED25519_REF10 = 1, KEY_TYPE_COUNT }; diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 4018c653a..63c6068bc 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -6,6 +6,20 @@ namespace model { namespace table { HederaAccount::HederaAccount() + : mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0) + { + + } + + HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) + : mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance) + { + + } + + HederaAccount::HederaAccount(const HederaAccountTuple& tuple) + : ModelBase(tuple.get<0>()), + mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()), mBalance(tuple.get<4>()), mUpdated(tuple.get<5>()) { } diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index c9c85b554..ca56dfd62 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -7,12 +7,14 @@ namespace model { namespace table { - typedef Poco::Tuple HederaAccountsTuple; + typedef Poco::Tuple HederaAccountTuple; class HederaAccount : public ModelBase { public: HederaAccount(); + HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + HederaAccount(const HederaAccountTuple& tuple); ~HederaAccount(); // generic db operations diff --git a/src/cpsp/adminTopic.cpsp b/src/cpsp/adminTopic.cpsp new file mode 100644 index 000000000..3eac5a976 --- /dev/null +++ b/src/cpsp/adminTopic.cpsp @@ -0,0 +1,23 @@ +<%@ page class="AdminTopicPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + +%> +<%% + const char* pageName = "Topic"; + + + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
    +

    Topic Admin Page

    +
    +
    + +
    +<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/header_large.cpsp b/src/cpsp/header_large.cpsp new file mode 100644 index 000000000..2aa8f5f4b --- /dev/null +++ b/src/cpsp/header_large.cpsp @@ -0,0 +1,19 @@ +<%! +#include "../ServerConfig.h" +%><%% + bool withMaterialIcons = false; +%> + + + + + +Gradido Login Server: <%= pageName %> + +<% if(withMaterialIcons) { %> + +<% } %> + + +
    +
    \ No newline at end of file From d8766f8d2d1f61efa67732b6c838503e04f0b7f2 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 13:14:33 +0200 Subject: [PATCH 062/195] add controller classes for new db tables crypto_keys and hedera_ids, update model tables for them --- src/cpp/Crypto/KeyPairHedera.cpp | 23 + src/cpp/Crypto/KeyPairHedera.h | 5 +- src/cpp/SingletonManager/SessionManager.cpp | 1251 +++++++++---------- src/cpp/controller/CryptoKey.cpp | 44 + src/cpp/controller/CryptoKey.h | 35 + src/cpp/controller/HederaId.cpp | 32 + src/cpp/controller/HederaId.h | 32 + src/cpp/model/table/CryptoKey.cpp | 16 + src/cpp/model/table/CryptoKey.h | 5 +- src/cpp/model/table/HederaId.cpp | 7 + src/cpp/model/table/HederaId.h | 1 + 11 files changed, 822 insertions(+), 629 deletions(-) create mode 100644 src/cpp/controller/CryptoKey.cpp create mode 100644 src/cpp/controller/CryptoKey.h create mode 100644 src/cpp/controller/HederaId.cpp create mode 100644 src/cpp/controller/HederaId.h diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 80c4649b1..a0e0c5d43 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -145,4 +145,27 @@ bool KeyPairHedera::verify(const unsigned char* message, size_t messageSize, Mem return false; } return true; +} + +MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr password) const +{ + if (password.isNull()) return nullptr; + if (!mPrivateKey) return nullptr; + + MemoryBin* encryptedKey = nullptr; + if (SecretKeyCryptography::AUTH_ENCRYPT_OK == password->encrypt(mPrivateKey, &encryptedKey)) { + return encryptedKey; + } + else { + return nullptr; + } + +} + +MemoryBin* KeyPairHedera::getPublicKeyCopy() const +{ + auto mm = MemoryManager::getInstance(); + auto public_key = mm->getFreeMemory(ed25519_pubkey_SIZE); + memcpy(*public_key, mPublicKey, ed25519_pubkey_SIZE); + return public_key; } \ No newline at end of file diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 358a3b680..871453afc 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -13,6 +13,7 @@ #include "sodium.h" +#include "SecretKeyCryptography.h" #include "iroha-ed25519/include/ed25519/ed25519.h" class KeyPairHedera : public IKeyPair @@ -34,6 +35,7 @@ public: bool verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const; inline const unsigned char* getPublicKey() const { return mPublicKey; } + MemoryBin* getPublicKeyCopy() const; inline bool isTheSame(const KeyPairHedera& b) const { return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); @@ -60,7 +62,8 @@ public: inline bool hasPrivateKey() const { return mPrivateKey != nullptr; } - + //! \brief only way to get a private key.. encrypted + MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; protected: diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 743f11d19..cac5354ee 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -1,626 +1,625 @@ -#include "SessionManager.h" -#include "ErrorManager.h" -#include "../ServerConfig.h" -#include "../Crypto/DRRandom.h" -#include "../controller/EmailVerificationCode.h" - -#include - - -SessionManager* SessionManager::getInstance() -{ - static SessionManager only; - return &only; -} - -SessionManager::SessionManager() - : mInitalized(false), mDeadLockedSessionCount(0) -{ - -} - -SessionManager::~SessionManager() -{ - if (mInitalized) { - deinitalize(); - } -} - - -bool SessionManager::init() -{ - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::init] exception timout mutex: %s\n", ex.displayText().data()); - return false; - } - //mWorkingMutex.lock(); - int i; - DISASM_MISALIGN; - for (i = 0; i < VALIDATE_MAX; i++) { - switch (i) { - //case VALIDATE_NAME: mValidations[i] = new Poco::RegularExpression("/^[a-zA-Z_ -]{3,}$/"); break; - case VALIDATE_NAME: mValidations[i] = new Poco::RegularExpression("^[^<>&;]{3,}$"); break; - case VALIDATE_EMAIL: mValidations[i] = new Poco::RegularExpression("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"); break; - case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-_])[A-Za-z0-9@$!%*?&+-_]{8,}$"); break; - case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; - case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; - case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break; - case VALIDATE_HAS_UPPERCASE_LETTER: - mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); - ServerConfig::g_ServerKeySeed->put(i, DRRandom::r64()); - break; - case VALIDATE_HAS_LOWERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[a-z].*"); break; - default: printf("[SessionManager::%s] unknown validation type\n", __FUNCTION__); - } - } - - - mInitalized = true; - mWorkingMutex.unlock(); - return true; -} - -void SessionManager::deinitalize() -{ - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::deinitalize] exception timout mutex: %s\n", ex.displayText().data()); - return; - } - //mWorkingMutex.lock(); - - while (mEmptyRequestStack.size()) { - mEmptyRequestStack.pop(); - } - - for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { - delete it->second; - } - mRequestSessionMap.clear(); - - for (int i = 0; i < VALIDATE_MAX; i++) { - delete mValidations[i]; - } - - printf("[SessionManager::deinitalize] count of dead locked sessions: %d\n", mDeadLockedSessionCount); - - mInitalized = false; - mWorkingMutex.unlock(); -} - -bool SessionManager::isValid(const std::string& subject, SessionValidationTypes validationType) -{ - if (validationType >= VALIDATE_MAX) { - return false; - } - return *mValidations[validationType] == subject; -} - -int SessionManager::generateNewUnusedHandle() -{ - int newHandle = 0; - int maxTrys = 0; - do { - newHandle = randombytes_random(); - maxTrys++; - } while (mRequestSessionMap.find(newHandle) != mRequestSessionMap.end() && maxTrys < 100); - - if (maxTrys >= 100 || 0 == newHandle) { - auto em = ErrorManager::getInstance(); - em->addError(new ParamError("SessionManager::generateNewUnusedHandle", "can't find new handle, have already ", std::to_string(mRequestSessionMap.size()))); - em->sendErrorsAsEmail(); - //printf("[SessionManager::%s] can't find new handle, have already: %d", - //__FUNCTION__, mRequestSessionMap.size()); - return 0; - } - return newHandle; -} - -Session* SessionManager::getNewSession(int* handle) -{ - const static char* functionName = "SessionManager::getNewSession"; - if (!mInitalized) { - printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); - return nullptr; - } - - // first check if we have any timeouted session to directly reuse it - checkTimeoutSession(); - - // lock - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[%s] exception timout mutex: %s\n", functionName, ex.displayText().data()); - return nullptr; - } - //mWorkingMutex.lock(); - - //UniLib::controller::TaskPtr checkSessionTimeout(new CheckSessionTimeouted); - //checkSessionTimeout->scheduleTask(checkSessionTimeout); - - // check if we have an existing session ready to use - while (mEmptyRequestStack.size() > 0) { - int local_handle = mEmptyRequestStack.top(); - mEmptyRequestStack.pop(); - auto resultIt = mRequestSessionMap.find(local_handle); - if (resultIt != mRequestSessionMap.end()) { - Session* result = resultIt->second; - // check if dead locked - if (result->tryLock()) { - result->unlock(); - if (!result->isActive()) { - result->reset(); - //mWorkingMutex.unlock(); - - if (handle) { - *handle = local_handle; - } - result->setActive(true); - mWorkingMutex.unlock(); - return result; - } - } - else { - ErrorList errors; - errors.addError(new Error(functionName, "found dead locked session, keeping in memory without reference")); - errors.addError(new ParamError(functionName, "last succeeded lock:", result->getLastSucceededLock().data())); - errors.sendErrorsAsEmail(); - - mRequestSessionMap.erase(local_handle); - } - - } - } - - // else create new RequestSession Object - // calculate random handle - // check if already exist, if get new - int newHandle = generateNewUnusedHandle(); - if (!newHandle) { - mWorkingMutex.unlock(); - return nullptr; - } - - auto requestSession = new Session(newHandle); - mRequestSessionMap.insert(std::pair(newHandle, requestSession)); - - requestSession->setActive(true); - //mWorkingMutex.unlock(); - - if (handle) { - *handle = newHandle; - } - //printf("[SessionManager::getNewSession] handle: %ld, sum: %u\n", newHandle, mRequestSessionMap.size()); - mWorkingMutex.unlock(); - return requestSession; - - - //return nullptr; -} - -bool SessionManager::releaseSession(int requestHandleSession) -{ - if (!mInitalized) { - printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); - return false; - } - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::releaseSession] exception timout mutex: %s\n", ex.displayText().data()); - return false; - } - //mWorkingMutex.lock(); - - auto it = mRequestSessionMap.find(requestHandleSession); - if (it == mRequestSessionMap.end()) { - //printf("[SessionManager::releaseRequestSession] requestSession with handle: %d not found\n", requestHandleSession); - mWorkingMutex.unlock(); - return false; - } - Session* session = it->second; - - // delete session, not reuse as workaround for server freeze bug - mRequestSessionMap.erase(requestHandleSession); - delete session; - mWorkingMutex.unlock(); - return true; - - // check if dead locked - if (session->tryLock()) { - session->unlock(); - session->reset(); - session->setActive(false); - } - else { - ErrorList errors; - errors.addError(new Error("SessionManager::releaseSession", "found dead locked session")); - errors.sendErrorsAsEmail(); - mRequestSessionMap.erase(requestHandleSession); - delete session; - mWorkingMutex.unlock(); - return true; - } - - // change request handle we don't want session hijacking - - // hardcoded disabled session max - if (mEmptyRequestStack.size() > 100) { - mRequestSessionMap.erase(requestHandleSession); - delete session; - mWorkingMutex.unlock(); - return true; - } - - int newHandle = generateNewUnusedHandle(); - //printf("[SessionManager::releseSession] oldHandle: %ld, newHandle: %ld\n", requestHandleSession, newHandle); - // erase after generating new number to prevent to getting the same number again - mRequestSessionMap.erase(requestHandleSession); - - if (!newHandle) { - delete session; - mWorkingMutex.unlock(); - return true; - } - - session->setHandle(newHandle); - mRequestSessionMap.insert(std::pair(newHandle, session)); - mEmptyRequestStack.push(newHandle); - - mWorkingMutex.unlock(); - return true; -} - -bool SessionManager::isExist(int requestHandleSession) -{ - static const char* function_name = "SessionManager::isExist"; - if (!mInitalized) { - printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); - return false; - } - bool result = false; - //mWorkingMutex.lock(); - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::isExist] exception timout mutex: %s\n", ex.displayText().data()); - return false; - } - auto it = mRequestSessionMap.find(requestHandleSession); - if (it != mRequestSessionMap.end()) { - result = true; - int iResult = it->second->isActive(); - if (-1 == iResult) { - auto em = ErrorManager::getInstance(); - em->addError(new Error(function_name, "session return locked")); - em->sendErrorsAsEmail(); - } - if (0 == iResult) { - printf("[SessionManager::isExist] session isn't active\n"); - } - } - mWorkingMutex.unlock(); - return result; -} - -Session* SessionManager::getSession(const Poco::Net::HTTPServerRequest& request) -{ - // check if user has valid session - Poco::Net::NameValueCollection cookies; - request.getCookies(cookies); - - int session_id = 0; - - try { - session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); - return getSession(session_id); - } - catch (...) {} - - return nullptr; -} - -Session* SessionManager::getSession(int handle) -{ - static const char* function_name = "SessionManager::getSession"; - if (!mInitalized) { - printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); - return nullptr; - } - if (0 == handle) return nullptr; - Session* result = nullptr; - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::getSession] exception timout mutex: %s\n", ex.displayText().data()); - return result; - } - //mWorkingMutex.lock(); - auto it = mRequestSessionMap.find(handle); - if (it != mRequestSessionMap.end()) { - result = it->second; - int iResult = result->isActive(); - if (iResult == -1) { - auto em = ErrorManager::getInstance(); - em->addError(new Error(function_name, "session is locked")); - em->sendErrorsAsEmail(); - mWorkingMutex.unlock(); - return nullptr; - } - if (0 == iResult) { - //printf("[SessionManager::getSession] session isn't active\n"); - mWorkingMutex.unlock(); - return nullptr; - } - //result->setActive(true); - result->updateTimeout(); - } - //printf("[SessionManager::getSession] handle: %ld\n", handle); - mWorkingMutex.unlock(); - return result; -} - -Session* SessionManager::findByEmailVerificationCode(const Poco::UInt64& emailVerificationCode) -{ - - auto email_verification = controller::EmailVerificationCode::load(emailVerificationCode); - if (email_verification.isNull()) return nullptr; - auto email_verification_model = email_verification->getModel(); - assert(email_verification_model && email_verification_model->getUserId() > 0); - - auto session = findByUserId(email_verification_model->getUserId()); - if (session) { - session->setEmailVerificationCodeObject(email_verification); - } - - return session; -} - -Session* SessionManager::findByUserId(int userId) -{ - assert(userId > 0); - static const char* function_name = "SessionManager::findByUserId"; - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::findByUserId] exception timout mutex: %s\n", ex.displayText().data()); - return nullptr; - } - //mWorkingMutex.lock(); - for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { - while (it->second->isDeadLocked()) - { - it = mRequestSessionMap.erase(it); - mDeadLockedSessionCount++; - auto em = ErrorManager::getInstance(); - em->addError(new ParamError("SessionManager::findByUserId", "new dead locked session found, sum dead lock sessions:", mDeadLockedSessionCount)); - em->sendErrorsAsEmail(); - } - auto user = it->second->getNewUser(); - auto em = ErrorManager::getInstance(); - if(!user) continue; - if (!user->getModel()) { - em->addError(new Error(function_name, "user getModel return nullptr")); - em->addError(new ParamError(function_name, "user id: ", userId)); - em->sendErrorsAsEmail(); - continue; - } - if (!user->getModel()->getID()) { - em->addError(new Error(function_name, "user id is zero")); - em->addError(new ParamError(function_name, "user id: ", userId)); - em->sendErrorsAsEmail(); - continue; - } - //assert(user->getModel() && user->getModel()->getID()); - if (userId == user->getModel()->getID()) { - mWorkingMutex.unlock(); - return it->second; - } - } - mWorkingMutex.unlock(); - return nullptr; -} - -std::vector SessionManager::findAllByUserId(int userId) -{ - assert(userId > 0); - std::vector result; - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::findAllByUserId] exception timout mutex: %s\n", ex.displayText().data()); - //mWorkingMutex.unlock(); - return result; - } - //mWorkingMutex.lock(); - for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { - if (it->second->isDeadLocked()) { - it = mRequestSessionMap.erase(it); - mDeadLockedSessionCount++; - } - auto user = it->second->getNewUser(); - if (userId == user->getModel()->getID()) { - //return it->second; - result.push_back(it->second); - } - } - //mWorkingMutex.unlock(); - mWorkingMutex.unlock(); - return result; -} - -Session* SessionManager::findByEmail(const std::string& email) -{ - assert(email.size() > 0); - - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException &ex) { - printf("[SessionManager::findByEmail] exception timout mutex: %s\n", ex.displayText().data()); - //mWorkingMutex.unlock(); - return nullptr; - } - //mWorkingMutex.lock(); - for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { - if (it->second->isDeadLocked()) { - it = mRequestSessionMap.erase(it); - mDeadLockedSessionCount++; - } - auto user = it->second->getNewUser(); -if (email == user->getModel()->getEmail()) { - return it->second; -} - } - mWorkingMutex.unlock(); - return nullptr; -} - -void SessionManager::checkTimeoutSession() -{ - - try { - //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); - mWorkingMutex.tryLock(500); - } - catch (Poco::TimeoutException& ex) { - printf("[SessionManager::checkTimeoutSession] exception timeout mutex: %s\n", ex.displayText().data()); - return; - } - //mWorkingMutex.lock(); - auto now = Poco::DateTime(); - // random variance within 10 seconds for timeout to make it harder to get information and hack the server - auto timeout = Poco::Timespan(ServerConfig::g_SessionTimeout * 60, randombytes_random() % 10000000); - //auto timeout = Poco::Timespan(1, 0); - std::stack toRemove; - for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { - - if (it->second->tryLock()) { - // skip already disabled sessions - if (!it->second->isActive()) { - it->second->unlock(); - continue; - } - } - else { - // skip dead locked sessions - continue; - } - - Poco::Timespan timeElapsed(now - it->second->getLastActivity()); - it->second->unlock(); - if (timeElapsed > timeout) { - toRemove.push(it->first); - } - } - mWorkingMutex.unlock(); - - while (toRemove.size() > 0) { - int handle = toRemove.top(); - toRemove.pop(); - releaseSession(handle); - } - -} - -void SessionManager::deleteLoginCookies(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response, Session* activeSession/* = nullptr*/) -{ - Poco::Net::NameValueCollection cookies; - request.getCookies(cookies); - // go from first login cookie - for (auto it = cookies.find("GRADIDO_LOGIN"); it != cookies.end(); it++) { - // break if no login any more - if (it->first != "GRADIDO_LOGIN") break; - // skip if it is from the active session - if (activeSession) { - try { - int session_id = atoi(it->second.data()); - if (activeSession->tryLock()) { - bool session_id_is_handle = session_id == activeSession->getHandle(); - activeSession->unlock(); - if (session_id_is_handle) continue; - } - } - catch (...) {} - } - // delete cookie - auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", it->second); - keks.setPath("/"); - // max age of 0 delete cookie - keks.setMaxAge(0); - response.addCookie(keks); - } - // delete also cake php session cookie - for (auto it = cookies.find("CAKEPHP"); it != cookies.end(); it++) { - if (it->first != "CAKEPHP") break; - // delete cookie - auto keks = Poco::Net::HTTPCookie("CAKEPHP", it->second); - keks.setPath("/"); - // max age of 0 delete cookie - keks.setMaxAge(0); - response.addCookie(keks); - //printf("remove PHP Kekse\n"); - } - - - //session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); -} - -bool SessionManager::checkPwdValidation(const std::string& pwd, ErrorList* errorReciver) -{ - if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) == ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) { - return true; - } - - if (!isValid(pwd, VALIDATE_PASSWORD)) { - errorReciver->addError(new Error("Passwort", "Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-_) ein!")); - - // @$!%*?&+- - if (pwd.size() < 8) { - errorReciver->addError(new Error("Passwort", "Dein Passwort ist zu kurz!")); - } - else if (!isValid(pwd, VALIDATE_HAS_LOWERCASE_LETTER)) { - errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Kleinbuchstaben!")); - } - else if (!isValid(pwd, VALIDATE_HAS_UPPERCASE_LETTER)) { - errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Großbuchstaben!")); - } - else if (!isValid(pwd, VALIDATE_HAS_NUMBER)) { - errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Zahlen!")); - } - else if (!isValid(pwd, VALIDATE_HAS_SPECIAL_CHARACTER)) { - errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Sonderzeichen (@$!%*?&+-)!")); - } - - return false; - } - return true; -} - - -int CheckSessionTimeouted::run() -{ - SessionManager::getInstance()->checkTimeoutSession(); - return 0; -} +#include "SessionManager.h" +#include "ErrorManager.h" +#include "../ServerConfig.h" +#include "../Crypto/DRRandom.h" +#include "../controller/EmailVerificationCode.h" + +#include + + +SessionManager* SessionManager::getInstance() +{ + static SessionManager only; + return &only; +} + +SessionManager::SessionManager() + : mInitalized(false), mDeadLockedSessionCount(0) +{ + +} + +SessionManager::~SessionManager() +{ + if (mInitalized) { + deinitalize(); + } +} + + +bool SessionManager::init() +{ + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::init] exception timout mutex: %s\n", ex.displayText().data()); + return false; + } + //mWorkingMutex.lock(); + int i; + DISASM_MISALIGN; + for (i = 0; i < VALIDATE_MAX; i++) { + switch (i) { + //case VALIDATE_NAME: mValidations[i] = new Poco::RegularExpression("/^[a-zA-Z_ -]{3,}$/"); break; + case VALIDATE_NAME: mValidations[i] = new Poco::RegularExpression("^[^<>&;]{3,}$"); break; + case VALIDATE_EMAIL: mValidations[i] = new Poco::RegularExpression("^[a-zA-Z0-9.!#$%&�*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"); break; + case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-_])[A-Za-z0-9@$!%*?&+-_]{8,}$"); break; + case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; + case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; + case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break; + case VALIDATE_HAS_UPPERCASE_LETTER: + mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); + ServerConfig::g_ServerKeySeed->put(i, DRRandom::r64()); + break; + case VALIDATE_HAS_LOWERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[a-z].*"); break; + default: printf("[SessionManager::%s] unknown validation type\n", __FUNCTION__); + } + } + + + mInitalized = true; + mWorkingMutex.unlock(); + return true; +} + +void SessionManager::deinitalize() +{ + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::deinitalize] exception timout mutex: %s\n", ex.displayText().data()); + return; + } + //mWorkingMutex.lock(); + + while (mEmptyRequestStack.size()) { + mEmptyRequestStack.pop(); + } + + for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { + delete it->second; + } + mRequestSessionMap.clear(); + + for (int i = 0; i < VALIDATE_MAX; i++) { + delete mValidations[i]; + } + + printf("[SessionManager::deinitalize] count of dead locked sessions: %d\n", mDeadLockedSessionCount); + + mInitalized = false; + mWorkingMutex.unlock(); +} + +bool SessionManager::isValid(const std::string& subject, SessionValidationTypes validationType) +{ + if (validationType >= VALIDATE_MAX) { + return false; + } + return *mValidations[validationType] == subject; +} + +int SessionManager::generateNewUnusedHandle() +{ + int newHandle = 0; + int maxTrys = 0; + do { + newHandle = randombytes_random(); + maxTrys++; + } while (mRequestSessionMap.find(newHandle) != mRequestSessionMap.end() && maxTrys < 100); + + if (maxTrys >= 100 || 0 == newHandle) { + auto em = ErrorManager::getInstance(); + em->addError(new ParamError("SessionManager::generateNewUnusedHandle", "can't find new handle, have already ", std::to_string(mRequestSessionMap.size()))); + em->sendErrorsAsEmail(); + //printf("[SessionManager::%s] can't find new handle, have already: %d", + //__FUNCTION__, mRequestSessionMap.size()); + return 0; + } + return newHandle; +} + +Session* SessionManager::getNewSession(int* handle) +{ + const static char* functionName = "SessionManager::getNewSession"; + if (!mInitalized) { + printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); + return nullptr; + } + + // first check if we have any timeouted session to directly reuse it + checkTimeoutSession(); + + // lock + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[%s] exception timout mutex: %s\n", functionName, ex.displayText().data()); + return nullptr; + } + //mWorkingMutex.lock(); + + //UniLib::controller::TaskPtr checkSessionTimeout(new CheckSessionTimeouted); + //checkSessionTimeout->scheduleTask(checkSessionTimeout); + + // check if we have an existing session ready to use + while (mEmptyRequestStack.size() > 0) { + int local_handle = mEmptyRequestStack.top(); + mEmptyRequestStack.pop(); + auto resultIt = mRequestSessionMap.find(local_handle); + if (resultIt != mRequestSessionMap.end()) { + Session* result = resultIt->second; + // check if dead locked + if (result->tryLock()) { + result->unlock(); + if (!result->isActive()) { + result->reset(); + //mWorkingMutex.unlock(); + + if (handle) { + *handle = local_handle; + } + result->setActive(true); + mWorkingMutex.unlock(); + return result; + } + } + else { + ErrorList errors; + errors.addError(new Error(functionName, "found dead locked session, keeping in memory without reference")); + errors.addError(new ParamError(functionName, "last succeeded lock:", result->getLastSucceededLock().data())); + errors.sendErrorsAsEmail(); + + mRequestSessionMap.erase(local_handle); + } + + } + } + + // else create new RequestSession Object + // calculate random handle + // check if already exist, if get new + int newHandle = generateNewUnusedHandle(); + if (!newHandle) { + mWorkingMutex.unlock(); + return nullptr; + } + + auto requestSession = new Session(newHandle); + mRequestSessionMap.insert(std::pair(newHandle, requestSession)); + + requestSession->setActive(true); + //mWorkingMutex.unlock(); + + if (handle) { + *handle = newHandle; + } + //printf("[SessionManager::getNewSession] handle: %ld, sum: %u\n", newHandle, mRequestSessionMap.size()); + mWorkingMutex.unlock(); + return requestSession; + + + //return nullptr; +} + +bool SessionManager::releaseSession(int requestHandleSession) +{ + if (!mInitalized) { + printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); + return false; + } + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::releaseSession] exception timout mutex: %s\n", ex.displayText().data()); + return false; + } + //mWorkingMutex.lock(); + + auto it = mRequestSessionMap.find(requestHandleSession); + if (it == mRequestSessionMap.end()) { + //printf("[SessionManager::releaseRequestSession] requestSession with handle: %d not found\n", requestHandleSession); + mWorkingMutex.unlock(); + return false; + } + Session* session = it->second; + + // delete session, not reuse as workaround for server freeze bug + mRequestSessionMap.erase(requestHandleSession); + delete session; + mWorkingMutex.unlock(); + return true; + + // check if dead locked + if (session->tryLock()) { + session->unlock(); + session->reset(); + session->setActive(false); + } + else { + ErrorList errors; + errors.addError(new Error("SessionManager::releaseSession", "found dead locked session")); + errors.sendErrorsAsEmail(); + mRequestSessionMap.erase(requestHandleSession); + delete session; + mWorkingMutex.unlock(); + return true; + } + + // change request handle we don't want session hijacking + + // hardcoded disabled session max + if (mEmptyRequestStack.size() > 100) { + mRequestSessionMap.erase(requestHandleSession); + delete session; + mWorkingMutex.unlock(); + return true; + } + + int newHandle = generateNewUnusedHandle(); + //printf("[SessionManager::releseSession] oldHandle: %ld, newHandle: %ld\n", requestHandleSession, newHandle); + // erase after generating new number to prevent to getting the same number again + mRequestSessionMap.erase(requestHandleSession); + + if (!newHandle) { + delete session; + mWorkingMutex.unlock(); + return true; + } + + session->setHandle(newHandle); + mRequestSessionMap.insert(std::pair(newHandle, session)); + mEmptyRequestStack.push(newHandle); + + mWorkingMutex.unlock(); + return true; +} + +bool SessionManager::isExist(int requestHandleSession) +{ + static const char* function_name = "SessionManager::isExist"; + if (!mInitalized) { + printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); + return false; + } + bool result = false; + //mWorkingMutex.lock(); + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::isExist] exception timout mutex: %s\n", ex.displayText().data()); + return false; + } + auto it = mRequestSessionMap.find(requestHandleSession); + if (it != mRequestSessionMap.end()) { + result = true; + int iResult = it->second->isActive(); + if (-1 == iResult) { + auto em = ErrorManager::getInstance(); + em->addError(new Error(function_name, "session return locked")); + em->sendErrorsAsEmail(); + } + if (0 == iResult) { + printf("[SessionManager::isExist] session isn't active\n"); + } + } + mWorkingMutex.unlock(); + return result; +} + +Session* SessionManager::getSession(const Poco::Net::HTTPServerRequest& request) +{ + // check if user has valid session + Poco::Net::NameValueCollection cookies; + request.getCookies(cookies); + + int session_id = 0; + + try { + session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); + return getSession(session_id); + } + catch (...) {} + + return nullptr; +} + +Session* SessionManager::getSession(int handle) +{ + static const char* function_name = "SessionManager::getSession"; + if (!mInitalized) { + printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__); + return nullptr; + } + if (0 == handle) return nullptr; + Session* result = nullptr; + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::getSession] exception timout mutex: %s\n", ex.displayText().data()); + return result; + } + //mWorkingMutex.lock(); + auto it = mRequestSessionMap.find(handle); + if (it != mRequestSessionMap.end()) { + printf("[SessionManager::getSession] found existing session, try if active...\n"); + result = it->second; + int iResult = result->isActive(); + if (iResult == -1) { + auto em = ErrorManager::getInstance(); + em->addError(new Error(function_name, "session is locked")); + em->sendErrorsAsEmail(); + mWorkingMutex.unlock(); + return nullptr; + } + if (0 == iResult) { + //printf("[SessionManager::getSession] session isn't active\n"); + mWorkingMutex.unlock(); + return nullptr; + } + //result->setActive(true); + result->updateTimeout(); + } + //printf("[SessionManager::getSession] handle: %ld\n", handle); + mWorkingMutex.unlock(); + return result; +} + +Session* SessionManager::findByEmailVerificationCode(const Poco::UInt64& emailVerificationCode) +{ + + auto email_verification = controller::EmailVerificationCode::load(emailVerificationCode); + if (email_verification.isNull()) return nullptr; + auto email_verification_model = email_verification->getModel(); + assert(email_verification_model && email_verification_model->getUserId() > 0); + + auto session = findByUserId(email_verification_model->getUserId()); + if (session) { + session->setEmailVerificationCodeObject(email_verification); + } + + return session; +} + +Session* SessionManager::findByUserId(int userId) +{ + assert(userId > 0); + static const char* function_name = "SessionManager::findByUserId"; + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::findByUserId] exception timout mutex: %s\n", ex.displayText().data()); + return nullptr; + } + //mWorkingMutex.lock(); + for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { + while (it->second->isDeadLocked()) + { + it = mRequestSessionMap.erase(it); + mDeadLockedSessionCount++; + auto em = ErrorManager::getInstance(); + em->addError(new ParamError("SessionManager::findByUserId", "new dead locked session found, sum dead lock sessions:", mDeadLockedSessionCount)); + em->sendErrorsAsEmail(); + } + auto user = it->second->getNewUser(); + auto em = ErrorManager::getInstance(); + if(!user) continue; + if (!user->getModel()) { + em->addError(new Error(function_name, "user getModel return nullptr")); + em->addError(new ParamError(function_name, "user id: ", userId)); + em->sendErrorsAsEmail(); + continue; + } + if (!user->getModel()->getID()) { + em->addError(new Error(function_name, "user id is zero")); + em->addError(new ParamError(function_name, "user id: ", userId)); + em->sendErrorsAsEmail(); + continue; + } + //assert(user->getModel() && user->getModel()->getID()); + if (userId == user->getModel()->getID()) { + mWorkingMutex.unlock(); + return it->second; + } + } + mWorkingMutex.unlock(); + return nullptr; +} + +std::vector SessionManager::findAllByUserId(int userId) +{ + assert(userId > 0); + std::vector result; + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::findAllByUserId] exception timout mutex: %s\n", ex.displayText().data()); + //mWorkingMutex.unlock(); + return result; + } + //mWorkingMutex.lock(); + for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { + if (it->second->isDeadLocked()) { + it = mRequestSessionMap.erase(it); + mDeadLockedSessionCount++; + } + auto user = it->second->getNewUser(); + if (userId == user->getModel()->getID()) { + //return it->second; + result.push_back(it->second); + } + } + //mWorkingMutex.unlock(); + mWorkingMutex.unlock(); + return result; +} + +Session* SessionManager::findByEmail(const std::string& email) +{ + assert(email.size() > 0); + + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::findByEmail] exception timout mutex: %s\n", ex.displayText().data()); + //mWorkingMutex.unlock(); + return nullptr; + } + //mWorkingMutex.lock(); + for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { + if (it->second->isDeadLocked()) { + it = mRequestSessionMap.erase(it); + mDeadLockedSessionCount++; + } + auto user = it->second->getNewUser(); + if (email == user->getModel()->getEmail()) { + return it->second; + } + } + mWorkingMutex.unlock(); + return nullptr; +} + +void SessionManager::checkTimeoutSession() +{ + try { + //Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500); + mWorkingMutex.tryLock(500); + } + catch (Poco::TimeoutException &ex) { + printf("[SessionManager::checkTimeoutSession] exception timeout mutex: %s\n", ex.displayText().data()); + return; + } + //mWorkingMutex.lock(); + auto now = Poco::DateTime(); + // random variance within 10 seconds for timeout to make it harder to get information and hack the server + auto timeout = Poco::Timespan(ServerConfig::g_SessionTimeout * 60, randombytes_random() % 10000000); + //auto timeout = Poco::Timespan(1, 0); + std::stack toRemove; + for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { + if (it->second->tryLock()) { + // skip already disabled sessions + if (!it->second->isActive()) { + it->second->unlock(); + continue; + } + } + else { + // skip dead locked sessions + continue; + } + + Poco::Timespan timeElapsed(now - it->second->getLastActivity()); + it->second->unlock(); + if (timeElapsed > timeout) { + toRemove.push(it->first); + } + } + mWorkingMutex.unlock(); + + while (toRemove.size() > 0) { + int handle = toRemove.top(); + toRemove.pop(); + releaseSession(handle); + } + +} + +void SessionManager::deleteLoginCookies(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response, Session* activeSession/* = nullptr*/) +{ + Poco::Net::NameValueCollection cookies; + request.getCookies(cookies); + // go from first login cookie + for (auto it = cookies.find("GRADIDO_LOGIN"); it != cookies.end(); it++) { + // break if no login any more + if (it->first != "GRADIDO_LOGIN") break; + // skip if it is from the active session + if (activeSession) { + try { + int session_id = atoi(it->second.data()); + if (activeSession->tryLock()) { + bool session_id_is_handle = session_id == activeSession->getHandle(); + activeSession->unlock(); + if (session_id_is_handle) continue; + } + } + catch (...) {} + } + // delete cookie + auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", it->second); + keks.setPath("/"); + // max age of 0 delete cookie + keks.setMaxAge(0); + response.addCookie(keks); + } + // delete also cake php session cookie + for (auto it = cookies.find("CAKEPHP"); it != cookies.end(); it++) { + if (it->first != "CAKEPHP") break; + // delete cookie + auto keks = Poco::Net::HTTPCookie("CAKEPHP", it->second); + keks.setPath("/"); + // max age of 0 delete cookie + keks.setMaxAge(0); + response.addCookie(keks); + //printf("remove PHP Kekse\n"); + } + + + //session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); +} + +bool SessionManager::checkPwdValidation(const std::string& pwd, ErrorList* errorReciver) +{ + if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) == ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) { + return true; + } + + if (!isValid(pwd, VALIDATE_PASSWORD)) { + errorReciver->addError(new Error("Passwort", "Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-_) ein!")); + + // @$!%*?&+- + if (pwd.size() < 8) { + errorReciver->addError(new Error("Passwort", "Dein Passwort ist zu kurz!")); + } + else if (!isValid(pwd, VALIDATE_HAS_LOWERCASE_LETTER)) { + errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Kleinbuchstaben!")); + } + else if (!isValid(pwd, VALIDATE_HAS_UPPERCASE_LETTER)) { + errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Großbuchstaben!")); + } + else if (!isValid(pwd, VALIDATE_HAS_NUMBER)) { + errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Zahlen!")); + } + else if (!isValid(pwd, VALIDATE_HAS_SPECIAL_CHARACTER)) { + errorReciver->addError(new Error("Passwort", "Dein Passwort enthält keine Sonderzeichen (@$!%*?&+-)!")); + } + + return false; + } + return true; +} + + +int CheckSessionTimeouted::run() +{ + SessionManager::getInstance()->checkTimeoutSession(); + return 0; +} diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp new file mode 100644 index 000000000..809673bc5 --- /dev/null +++ b/src/cpp/controller/CryptoKey.cpp @@ -0,0 +1,44 @@ + +#include "CryptoKey.h" + +namespace controller { + + CryptoKey::CryptoKey(model::table::CryptoKey* dbModel) + { + mDBModel = dbModel; + } + + CryptoKey::~CryptoKey() + { + + } + + Poco::AutoPtr CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user) + { + auto mm = MemoryManager::getInstance(); + + auto encrypted_priv_key = hederaKeyPair->getCryptedPrivKey(user->getPassword()); + auto public_key = hederaKeyPair->getPublicKeyCopy(); + + auto db = new model::table::CryptoKey(encrypted_priv_key, public_key, model::table::KEY_TYPE_ED25519_HEDERA); + + mm->releaseMemory(encrypted_priv_key); + mm->releaseMemory(public_key); + + auto cryptoKey = new CryptoKey(db); + return Poco::AutoPtr(cryptoKey); + } + + Poco::AutoPtr CryptoKey::load(int id) + { + auto db = new model::table::CryptoKey(); + if (1 == db->loadFromDB("id", id)) { + auto cryptoKey = new CryptoKey(db); + return Poco::AutoPtr(cryptoKey); + } + return nullptr; + } + + +} + diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h new file mode 100644 index 000000000..9e76123ef --- /dev/null +++ b/src/cpp/controller/CryptoKey.h @@ -0,0 +1,35 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE + +#include "../model/table/CryptoKey.h" +#include "../Crypto/KeyPairHedera.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" +#include "User.h" + +namespace controller { + class CryptoKey : public TableControllerBase + { + public: + + ~CryptoKey(); + + static Poco::AutoPtr create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user); + + //! if returned ptr is NULL, dataset not found + static Poco::AutoPtr load(int id); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + CryptoKey(model::table::CryptoKey* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE \ No newline at end of file diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp new file mode 100644 index 000000000..e6d281907 --- /dev/null +++ b/src/cpp/controller/HederaId.cpp @@ -0,0 +1,32 @@ +#include "HederaId.h" + +namespace controller { + + HederaId::HederaId(model::table::HederaId* dbModel) + { + mDBModel = dbModel; + } + + HederaId::~HederaId() + { + + } + + Poco::AutoPtr HederaId::create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num) + { + auto db = new model::table::HederaId(shardNum, realmNum, num); + + auto hedera_id = new HederaId(db); + return Poco::AutoPtr(hedera_id); + } + + Poco::AutoPtr HederaId::load(int id) + { + auto db = new model::table::HederaId(); + if (1 == db->loadFromDB("id", id)) { + auto cryptoKey = new HederaId(db); + return Poco::AutoPtr(cryptoKey); + } + return nullptr; + } +} \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h new file mode 100644 index 000000000..f02e69373 --- /dev/null +++ b/src/cpp/controller/HederaId.h @@ -0,0 +1,32 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE + +#include "../model/table/HederaId.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + class HederaId : public TableControllerBase + { + public: + + ~HederaId(); + + static Poco::AutoPtr create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); + + static Poco::AutoPtr load(int id); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + HederaId(model::table::HederaId* dbModel); + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index 201047a5b..d36f44de6 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -9,6 +9,22 @@ namespace model { } + CryptoKey::CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType) + : mKeyType(keyType) + { + if (!privateKey) { + mPrivateKey = Poco::Nullable(); + } else { + mPrivateKey = Poco::Nullable(Poco::Data::BLOB(*privateKey, privateKey->size())); + } + + if (!publicKey) { + mPublicKey = Poco::Nullable(); + } else { + mPublicKey = Poco::Nullable(Poco::Data::BLOB(*publicKey, publicKey->size())); + } + } + CryptoKey::~CryptoKey() { diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index f4fd8bebf..58d6df5dc 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -8,8 +8,8 @@ namespace model { namespace table { enum KeyType { - KEY_TYPE_SODIUM_ED25519 = 0, - KEY_TYPE_ED25519_REF10 = 1, + KEY_TYPE_ED25519_SODIUM = 0, + KEY_TYPE_ED25519_HEDERA = 1, KEY_TYPE_COUNT }; @@ -17,6 +17,7 @@ namespace model { { public: CryptoKey(); + CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType); ~CryptoKey(); // generic db operations diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index b048a0d71..a4f25cc78 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -5,6 +5,13 @@ using namespace Poco::Data::Keywords; namespace model { namespace table { HederaId::HederaId() + : mShardNum(0), mRealmNum(0), mNum(0) + { + + } + + HederaId::HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num) + : mShardNum(shardNum), mRealmNum(realmNum), mNum(num) { } diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index ef35b2e70..c36d1f656 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -11,6 +11,7 @@ namespace model { { public: HederaId(); + HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); ~HederaId(); // generic db operations From 87431e8a70632fb3c6aa5e81df25be2761248e2b Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 28 Aug 2020 18:06:29 +0200 Subject: [PATCH 063/195] save entry of hedera account in db --- skeema/gradido_login/hedera_accounts.sql | 1 + .../HTTPInterface/AdminHederaAccountPage.cpp | 127 ++++++++++++++++-- src/cpp/SingletonManager/SessionManager.cpp | 2 + src/cpp/SingletonManager/SessionManager.h | 2 + src/cpp/controller/HederaAccount.cpp | 4 +- src/cpp/controller/HederaAccount.h | 2 +- src/cpp/model/table/CryptoKey.cpp | 4 +- src/cpp/model/table/HederaAccount.cpp | 29 ++-- src/cpp/model/table/HederaAccount.h | 12 +- 9 files changed, 159 insertions(+), 24 deletions(-) diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql index 23ffa33d1..c8fcff4eb 100644 --- a/skeema/gradido_login/hedera_accounts.sql +++ b/skeema/gradido_login/hedera_accounts.sql @@ -4,6 +4,7 @@ CREATE TABLE `hedera_accounts` ( `account_hedera_id` int unsigned NOT NULL, `account_key_id` int unsigned NOT NULL, `balance` bigint unsigned NOT NULL DEFAULT '0', + `network_type` int NOT NULL DEFAULT '0', `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `account_hedera_id` (`account_hedera_id`), diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 0500a8996..884bc1cdc 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -7,7 +7,13 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - #include "../controller/HederaAccount.h" + +#include "../controller/HederaAccount.h" +#include "../controller/HederaId.h" +#include "../controller/CryptoKey.h" +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" + #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" #include "../ServerConfig.h" @@ -27,15 +33,104 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + auto user = mSession->getNewUser(); // add if(!form.empty()) { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* privateKey = nullptr; + MemoryBin* publicKey = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + if(!hedera_id->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving hedera id in DB")); + } + + privateKey = DataTypeConverter::hexToBin(privateKeyString); + publicKey = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(privateKey, publicKey); + mm->releaseMemory(privateKey); + mm->releaseMemory(publicKey); + auto crypto_key = controller::CryptoKey::create(&key_pair, user); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + + if(0 == errorCount()) { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + } } - #line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" @@ -74,7 +169,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 21 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 116 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -84,15 +179,31 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
    \n"; diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index cac5354ee..d7286f1fd 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -48,6 +48,8 @@ bool SessionManager::init() case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-_])[A-Za-z0-9@$!%*?&+-_]{8,}$"); break; case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; + case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; + case VALIDATE_ONLY_HEX: mValidations[i] = new Poco::RegularExpression("^(0x)?[a-fA-F0-9]*$"); break; case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break; case VALIDATE_HAS_UPPERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index 2f720b82b..e3202d536 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -28,6 +28,8 @@ enum SessionValidationTypes { VALIDATE_PASSWORD, VALIDATE_PASSPHRASE, VALIDATE_HAS_NUMBER, + VALIDATE_ONLY_INTEGER, + VALIDATE_ONLY_HEX, VALIDATE_HAS_SPECIAL_CHARACTER, VALIDATE_HAS_UPPERCASE_LETTER, VALIDATE_HAS_LOWERCASE_LETTER, diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 9a858bd7c..42a08eb27 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -13,9 +13,9 @@ namespace controller { } - Poco::AutoPtr HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) + Poco::AutoPtr HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, model::table::HederaNetworkType type/* = HEDERA_MAINNET*/) { - auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance); + auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance, type); auto group = new HederaAccount(db); return Poco::AutoPtr(group); } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 9efd89c12..fd2cb4b23 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -14,7 +14,7 @@ namespace controller { ~HederaAccount(); - static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); static std::vector> load(const std::string& alias); static std::vector> listAll(); diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index d36f44de6..9588f57e7 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -43,8 +43,8 @@ namespace model { const char* CryptoKey::typeToString(KeyType type) { switch (type) { - case KEY_TYPE_ED25519_REF10: return "ed25519 ref10"; - case KEY_TYPE_SODIUM_ED25519: return "sodium ed22519"; + case KEY_TYPE_ED25519_SODIUM: return "ed25519 ref10"; + case KEY_TYPE_ED25519_HEDERA: return "sodium ed22519"; } return ""; } diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 63c6068bc..06538fdcb 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -6,20 +6,21 @@ namespace model { namespace table { HederaAccount::HederaAccount() - : mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0) + : mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0), mType(0) { } - HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/) - : mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance) + HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, HederaNetworkType type /*= HEDERA_MAINNET*/) + : mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance), mType(type) { } HederaAccount::HederaAccount(const HederaAccountTuple& tuple) : ModelBase(tuple.get<0>()), - mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()), mBalance(tuple.get<4>()), mUpdated(tuple.get<5>()) + mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()), + mBalance(tuple.get<4>()), mType(tuple.get<5>()), mUpdated(tuple.get<6>()) { } @@ -37,18 +38,28 @@ namespace model { ss << "account crypto key id: " << std::to_string(mAccountKeyId) << std::endl; // balance in tinybars, 100,000,000 tinybar = 1 HashBar ss << "account balance: " << std::to_string((double)(mBalance) * 100000000.0) << " HBAR" << std::endl; + ss << "Hedera Net Type: " << hederaNetworkTypeToString((HederaNetworkType)mType) << std::endl; ss << "last update: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl; return ss.str(); } + const char* HederaAccount::hederaNetworkTypeToString(HederaNetworkType type) + { + switch (type) { + case HEDERA_MAINNET: return "Mainnet"; + case HEDERA_TESTNET: return "Testnet"; + default: return ""; + } + } + Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); - select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, network_type, updated FROM " << getTableName() << " where " << fieldName << " = ?" - , into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mUpdated); + , into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mType), into(mUpdated); return select; @@ -57,7 +68,7 @@ namespace model { Poco::Data::Statement HederaAccount::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); - select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, updated FROM " << getTableName() + select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, network_type, updated FROM " << getTableName() << " where " << fieldName << " LIKE ?"; return select; @@ -77,8 +88,8 @@ namespace model { Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (user_id, account_hedera_id, account_key_id, balance) VALUES(?,?,?,?)" - , use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance); + << " (user_id, account_hedera_id, account_key_id, balance, network_type) VALUES(?,?,?,?,?)" + , use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance), use(mType); unlock(); return insert; } diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index ca56dfd62..2219fc521 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -7,13 +7,19 @@ namespace model { namespace table { - typedef Poco::Tuple HederaAccountTuple; + typedef Poco::Tuple HederaAccountTuple; + + enum HederaNetworkType { + HEDERA_MAINNET, + HEDERA_TESTNET, + HEDERA_NET_COUNT + }; class HederaAccount : public ModelBase { public: HederaAccount(); - HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0); + HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, HederaNetworkType type = HEDERA_MAINNET); HederaAccount(const HederaAccountTuple& tuple); ~HederaAccount(); @@ -21,6 +27,7 @@ namespace model { const char* getTableName() const { return "hedera_accounts"; } std::string toString(); + static const char* hederaNetworkTypeToString(HederaNetworkType type); protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); @@ -32,6 +39,7 @@ namespace model { int mAccountHederaId; int mAccountKeyId; Poco::UInt64 mBalance; + int mType; Poco::DateTime mUpdated; }; From 3d4f0d7b64bb06cdd8bc5e391006760d41b9c06e Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 31 Aug 2020 11:23:58 +0200 Subject: [PATCH 064/195] show and add node server and hedera accounts, model, controller and page --- skeema/gradido_login/crypto_keys.sql | 3 +- skeema/gradido_login/hedera_accounts.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 12 +- src/cpp/Crypto/KeyPairHedera.h | 1 + src/cpp/HTTPInterface/AdminGroupsPage.cpp | 83 ++-- .../HTTPInterface/AdminHederaAccountPage.cpp | 112 ++++-- src/cpp/HTTPInterface/AdminNodeServerPage.cpp | 363 ++++++++++++++++++ src/cpp/HTTPInterface/AdminNodeServerPage.h | 20 + .../PageRequestHandlerFactory.cpp | 6 + .../SingletonManager/ConnectionManager.cpp | 2 + src/cpp/SingletonManager/SessionManager.cpp | 2 + src/cpp/SingletonManager/SessionManager.h | 1 + src/cpp/controller/CryptoKey.cpp | 23 ++ src/cpp/controller/CryptoKey.h | 2 + src/cpp/controller/Group.cpp | 2 +- src/cpp/controller/HederaAccount.cpp | 14 +- src/cpp/controller/HederaAccount.h | 7 +- src/cpp/controller/NodeServer.cpp | 145 +++++++ src/cpp/controller/NodeServer.h | 52 +++ src/cpp/model/table/HederaAccount.h | 9 + src/cpp/model/table/HederaId.cpp | 31 +- src/cpp/model/table/HederaId.h | 3 + src/cpp/model/table/ModelBase.cpp | 11 +- src/cpp/model/table/NodeServer.cpp | 114 ++++++ src/cpp/model/table/NodeServer.h | 71 ++++ src/cpsp/adminGroups.cpsp | 22 +- src/cpsp/adminNodeServer.cpsp | 200 ++++++++++ src/cpsp/header_large.cpsp | 10 + 28 files changed, 1229 insertions(+), 94 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminNodeServerPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminNodeServerPage.h create mode 100644 src/cpp/controller/NodeServer.cpp create mode 100644 src/cpp/controller/NodeServer.h create mode 100644 src/cpp/model/table/NodeServer.cpp create mode 100644 src/cpp/model/table/NodeServer.h create mode 100644 src/cpsp/adminNodeServer.cpsp diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index 43b511db2..c90750ae3 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -3,5 +3,6 @@ CREATE TABLE `crypto_keys` ( `private_key` varbinary(64) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE(`public_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/skeema/gradido_login/hedera_accounts.sql b/skeema/gradido_login/hedera_accounts.sql index c8fcff4eb..8ce24b54d 100644 --- a/skeema/gradido_login/hedera_accounts.sql +++ b/skeema/gradido_login/hedera_accounts.sql @@ -5,7 +5,7 @@ CREATE TABLE `hedera_accounts` ( `account_key_id` int unsigned NOT NULL, `balance` bigint unsigned NOT NULL DEFAULT '0', `network_type` int NOT NULL DEFAULT '0', - `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `account_hedera_id` (`account_hedera_id`), UNIQUE KEY `account_key_id` (`account_key_id`) diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index a0e0c5d43..0a3bf4bc2 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -46,9 +46,10 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi default: throw std::exception("[KeyPairHedera] invalid private key"); } - crypto_sign_ed25519_sk_to_pk(mPublicKey, *mPrivateKey); + + // check public } - else if (publicKey) { + if (publicKey) { switch (publicKey->size()) { case 32: { // raw public key @@ -64,8 +65,13 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi throw std::exception("[KeyPairHedera] invalid public key"); } } + auto public_key_2 = mm->getFreeMemory(ed25519_pubkey_SIZE); + crypto_sign_ed25519_sk_to_pk(*public_key_2, *mPrivateKey); + if (sodium_memcmp(*public_key_2, mPublicKey, ed25519_pubkey_SIZE) != 0) { + throw "public keys not match"; + } - + mm->releaseMemory(public_key_2); mm->releaseMemory(derPrefixPriv); mm->releaseMemory(derPrefixPub); } diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 871453afc..115beebdb 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -70,6 +70,7 @@ protected: KeyPairHedera(); void createKeyFromSeed(const MemoryBin* seed); + private: // 64 Byte //! \brief ed25519 libsodium private key diff --git a/src/cpp/HTTPInterface/AdminGroupsPage.cpp b/src/cpp/HTTPInterface/AdminGroupsPage.cpp index 1e6619801..7e38cfde2 100644 --- a/src/cpp/HTTPInterface/AdminGroupsPage.cpp +++ b/src/cpp/HTTPInterface/AdminGroupsPage.cpp @@ -8,7 +8,7 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" #include "../controller/Group.h" -#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" #include "../ServerConfig.h" @@ -55,14 +55,14 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: //auto groups = controller::Group::load("gdd1"); //std::vector> groups; -#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" bool withMaterialIcons = false; std::ostream& _responseStream = response.send(); Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; responseStream << "\n"; - // begin include header.cpsp + // begin include header_large.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; @@ -70,47 +70,48 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: responseStream << "\n"; responseStream << "\n"; responseStream << "Gradido Login Server: "; -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" responseStream << ( pageName ); responseStream << "\n"; responseStream << "\n"; -#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" if(withMaterialIcons) { responseStream << "\n"; responseStream << "\n"; -#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" } responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << " "; - // end include header.cpsp + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t
    "; + // end include header_large.cpsp responseStream << "\n"; #line 38 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( getErrorsHtml() ); @@ -122,11 +123,11 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: responseStream << "\t\t
    \t\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t\t
    ID
    \n"; - responseStream << "\t\t\t\t
    Name
    \n"; - responseStream << "\t\t\t\t
    Alias
    \n"; - responseStream << "\t\t\t\t
    Url
    \n"; - responseStream << "\t\t\t\t
    "; + responseStream << "\t\t\t\t
    ID
    \n"; + responseStream << "\t\t\t\t
    Name
    \n"; + responseStream << "\t\t\t\t
    Alias
    \n"; + responseStream << "\t\t\t\t
    Url
    \n"; + responseStream << "\t\t\t\t
    "; #line 50 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( gettext("Description") ); responseStream << "
    \n"; @@ -136,23 +137,23 @@ void AdminGroupsPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco: for(auto it = groups.begin(); it != groups.end(); it++) { auto group_model = (*it)->getModel(); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; - responseStream << "\t\t\t\t\t
    "; + responseStream << "\t\t\t\t\t
    "; #line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getID() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    "; + responseStream << "\t\t\t\t\t
    "; #line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getName() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    "; + responseStream << "\t\t\t\t\t
    "; #line 57 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getAlias() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    "; + responseStream << "\t\t\t\t\t
    "; #line 58 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getUrl() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    "; + responseStream << "\t\t\t\t\t
    "; #line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminGroups.cpsp" responseStream << ( group_model->getDescription()); responseStream << "
    \n"; diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 884bc1cdc..0de7a6922 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -55,8 +55,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request int num = 0; int networkType = 0; - MemoryBin* privateKey = nullptr; - MemoryBin* publicKey = nullptr; + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; // validate if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { @@ -100,22 +100,22 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(0 == errorCount()) { auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); - if(!hedera_id->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving hedera id in DB")); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); } - - privateKey = DataTypeConverter::hexToBin(privateKeyString); - publicKey = DataTypeConverter::hexToBin(publicKeyString); - - - KeyPairHedera key_pair(privateKey, publicKey); - mm->releaseMemory(privateKey); - mm->releaseMemory(publicKey); - auto crypto_key = controller::CryptoKey::create(&key_pair, user); - if(!crypto_key->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving crypto key in DB")); - } - if(0 == errorCount()) { auto hedera_account = controller::HederaAccount::create( user->getModel()->getID(), @@ -128,10 +128,15 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request addError(new Error("DB Error", "Error saving hedera account into DB")); } } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); } } + // list accounts + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); #line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" @@ -166,13 +171,74 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\n"; responseStream << "\n"; responseStream << "
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t
    \n"; responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 116 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t

    Deine Hedera Accounts

    \n"; + responseStream << "\t\t
    \t\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t
    Hedera Id
    \t\t\t\n"; + responseStream << "\t\t\t\t
    Balance
    \n"; + responseStream << "\t\t\t\t
    Server Type
    \n"; + responseStream << "\t\t\t\t
    Last Updated
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 134 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { + auto hedera_account_model = (*it)->getModel(); + responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( (*it)->getHederaId()->getModel()->toString() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( hedera_account_model->getBalanceDouble() ); + responseStream << " hbar
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 140 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 141 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( hedera_account_model->getUpdatedString() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + } responseStream << "\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t

    Einen neuen Account anlegen

    \n"; responseStream << "\t
    \n"; @@ -189,21 +255,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\n"; diff --git a/src/cpp/HTTPInterface/AdminNodeServerPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerPage.cpp new file mode 100644 index 000000000..c6c786aeb --- /dev/null +++ b/src/cpp/HTTPInterface/AdminNodeServerPage.cpp @@ -0,0 +1,363 @@ +#include "AdminNodeServerPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + + +#include "../controller/NodeServer.h" +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" +#include "../lib/DataTypeConverter.h" + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +AdminNodeServerPage::AdminNodeServerPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminNodeServerPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + + const char* pageName = "Node Server"; + auto sm = SessionManager::getInstance(); + + // add + if(!form.empty()) { + // collect + auto url = form.get("node-server-url", ""); + auto portString = form.get("node-server-port", ""); + auto nodeServerTypeString = form.get("node-server-type", "0"); + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto nodeServerGroupString = form.get("node-server-group", ""); + + int port = 0; + int shardNum = 0; + int realmNum = 0; + int num = 0; + model::table::NodeServerType nodeServerType = model::table::NODE_SERVER_NONE; + int group_id = 0; + + + // validate + if(!sm->isValid(url, VALIDATE_ONLY_URL)) { + addError(new ParamError("Node Server", "Url not valid, must start with http or https", url)); + + } + if(!sm->isValid(portString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server", "Port isn't valid integer")); + } else { + if(DataTypeConverter::strToInt(portString, port) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting port to int")); + } + } + + if(!sm->isValid(nodeServerTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server Type", "not integer")); + } else { + int node_server_type_int = 0; + if(DataTypeConverter::strToInt(nodeServerTypeString, node_server_type_int) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting node server type to int")); + } + if(node_server_type_int < 0 || node_server_type_int >= (int)model::table::NODE_SERVER_TYPE_COUNT) { + addError(new Error("Node Server Type", "invalid value")); + } else { + nodeServerType = (model::table::NodeServerType)node_server_type_int; + } + } + if(model::table::NodeServerIsHederaNode(nodeServerType)) { + + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + } else if(model::table::NodeServerHasGroup(nodeServerType)) { + if(!sm->isValid(nodeServerGroupString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(nodeServerGroupString, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } + } + + + + if(0 == errorCount()) { + int hedera_id_int = 0; + if(NodeServerIsHederaNode(nodeServerType)) { + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + hedera_id_int = hedera_id->getModel()->getID(); + } + + auto node_server = controller::NodeServer::create( + url, port, group_id, (model::table::NodeServerType)nodeServerType, hedera_id_int + ); + if(!node_server->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving Node Server in DB")); + } + } + } + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } + + auto node_servers = controller::NodeServer::listAll(); + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t
    "; + // end include header_large.cpsp + responseStream << "\n"; +#line 126 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t

    Alle Node Server

    \n"; + responseStream << "\t\t
    \t\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t
    Server Type
    \n"; + responseStream << "\t\t\t\t
    Url:Port
    \n"; + responseStream << "\t\t\t\t
    Group / Hedera Id
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + for(auto it = node_servers.begin(); it != node_servers.end(); it++) { + auto node_server_model = (*it)->getModel(); + responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 142 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( model::table::NodeServer::nodeServerTypeToString(node_server_model->getNodeServerType()) ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( node_server_model->getUrlWithPort() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t\t"; +#line 145 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + if(node_server_model->isHederaNode()) { + auto hedera_id_model = (*it)->getHederaId()->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t"; +#line 147 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( hedera_id_model->toString() ); + responseStream << "\n"; + responseStream << "\t\t\t\t\t\t"; +#line 148 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } else if(node_server_model->hasGroup()){ + auto groupIt = group_indices.find(node_server_model->getGroupId()); + if(groupIt != group_indices.end()) { + auto group_model = groups[groupIt->second]->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t\tgetDescription() ); + responseStream << "\">"; +#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( group_model->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t"; +#line 153 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } else { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t\t"; +#line 154 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + responseStream << ( node_server_model->getGroupId() ); + responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\t"; +#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\t"; +#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t
    \n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 159 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServer.cpsp" + } responseStream << "\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t

    Ein Node Server hinzufügen

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\tNur für Hedera Nodes\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\tNur für Gradido Nodes\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + // begin include footer.cpsp + responseStream << "
    \n"; + responseStream << "

    Copyright © Gradido 2020

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "

    Login Server in Entwicklung

    \n"; + responseStream << "

    Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminNodeServerPage.h b/src/cpp/HTTPInterface/AdminNodeServerPage.h new file mode 100644 index 000000000..4a60b45e7 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminNodeServerPage.h @@ -0,0 +1,20 @@ +#ifndef AdminNodeServerPage_INCLUDED +#define AdminNodeServerPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminNodeServerPage: public SessionHTTPRequestHandler +{ +public: + AdminNodeServerPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminNodeServerPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 11cdb7d78..b31e742c0 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -30,6 +30,7 @@ #include "AdminGroupsPage.h" #include "AdminTopicPage.h" #include "AdminHederaAccountPage.h" +#include "AdminNodeServerPage.h" #include "DecodeTransactionPage.h" #include "RepairDefectPassphrase.h" @@ -224,6 +225,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/nodes") { + auto pageRequestHandler = new AdminNodeServerPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/SingletonManager/ConnectionManager.cpp b/src/cpp/SingletonManager/ConnectionManager.cpp index f844a6aa1..93bf1eb6a 100644 --- a/src/cpp/SingletonManager/ConnectionManager.cpp +++ b/src/cpp/SingletonManager/ConnectionManager.cpp @@ -73,6 +73,7 @@ Poco::Data::Session ConnectionManager::getConnection(ConnectionType type) throw Poco::NotFoundException("Connection Type unknown", std::to_string(type)); } auto session = mSessionPools.getPool(mSessionPoolNames[type]).get(); + //return mSessionPoolNames[type]; /*if (!session.isConnected()) { @@ -85,6 +86,7 @@ Poco::Data::Session ConnectionManager::getConnection(ConnectionType type) sendErrorsAsEmail(); return mSessionPools.getPool(mSessionPoolNames[type]).get(); } + }*/ //std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); //printf("[getConnection] %s impl: %p\n", dateTimeString.data(), session.impl()); diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index d7286f1fd..1f7e87303 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -50,6 +50,8 @@ bool SessionManager::init() case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; case VALIDATE_ONLY_HEX: mValidations[i] = new Poco::RegularExpression("^(0x)?[a-fA-F0-9]*$"); break; + //case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}$"); break; + case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\/?"); break; case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break; case VALIDATE_HAS_UPPERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index e3202d536..e1469d539 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -30,6 +30,7 @@ enum SessionValidationTypes { VALIDATE_HAS_NUMBER, VALIDATE_ONLY_INTEGER, VALIDATE_ONLY_HEX, + VALIDATE_ONLY_URL, VALIDATE_HAS_SPECIAL_CHARACTER, VALIDATE_HAS_UPPERCASE_LETTER, VALIDATE_HAS_LOWERCASE_LETTER, diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 809673bc5..2e7d343ec 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -1,5 +1,6 @@ #include "CryptoKey.h" +#include "../SingletonManager/ErrorManager.h" namespace controller { @@ -39,6 +40,28 @@ namespace controller { return nullptr; } + Poco::AutoPtr CryptoKey::load(MemoryBin* publicKey) + { + return load(*publicKey, publicKey->size()); + } + + Poco::AutoPtr CryptoKey::load(const unsigned char* publicKey, size_t size) + { + assert(publicKey); + assert(size); + + Poco::Data::BLOB public_key_blob(publicKey, size); + auto db = new model::table::CryptoKey(); + auto count = db->loadFromDB("public_key", public_key_blob); + if (!count) return nullptr; + if (1 == count) return new CryptoKey(db); + + auto em = ErrorManager::getInstance(); + em->addError(new Error("CryptoKey::load", "found more than one crypto key with same public key")); + em->sendErrorsAsEmail(); + return nullptr; + } + } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index 9e76123ef..6e4e110bb 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -20,6 +20,8 @@ namespace controller { //! if returned ptr is NULL, dataset not found static Poco::AutoPtr load(int id); + static Poco::AutoPtr load(MemoryBin* publicKey); + static Poco::AutoPtr load(const unsigned char* publicKey, size_t size); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } diff --git a/src/cpp/controller/Group.cpp b/src/cpp/controller/Group.cpp index d5b3eb2ba..2d809da07 100644 --- a/src/cpp/controller/Group.cpp +++ b/src/cpp/controller/Group.cpp @@ -23,7 +23,7 @@ namespace controller { std::vector> Group::load(const std::string& alias) { auto db = new model::table::Group(); - auto group_list = db->loadFromDB("alias", alias, 0); + auto group_list = db->loadFromDB("alias", alias, 1); std::vector> resultVector; resultVector.reserve(group_list.size()); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 42a08eb27..9f4ff5b40 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -20,15 +20,19 @@ namespace controller { return Poco::AutoPtr(group); } - std::vector> HederaAccount::load(const std::string& alias) + std::vector> HederaAccount::load(const std::string& fieldName, int fieldValue) { auto db = new model::table::HederaAccount(); - auto group_list = db->loadFromDB("alias", alias, 0); + auto hedera_account_list = db->loadFromDB(fieldName, fieldValue, 2); std::vector> resultVector; - resultVector.reserve(group_list.size()); - for (auto it = group_list.begin(); it != group_list.end(); it++) { - resultVector.push_back(new HederaAccount(new model::table::HederaAccount(*it))); + resultVector.reserve(hedera_account_list.size()); + for (auto it = hedera_account_list.begin(); it != hedera_account_list.end(); it++) { + //mHederaID + auto db = new model::table::HederaAccount(*it); + auto hedera_account = new HederaAccount(db); + hedera_account->mHederaID = HederaId::load(db->getAccountHederaId()); + resultVector.push_back(hedera_account); } return resultVector; } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index fd2cb4b23..dd4c97435 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -1,6 +1,7 @@ #ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE #define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE +#include "../controller/HederaId.h" #include "../model/table/HederaAccount.h" #include "Poco/SharedPtr.h" @@ -11,21 +12,23 @@ namespace controller { class HederaAccount : public TableControllerBase { public: - ~HederaAccount(); static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); - static std::vector> load(const std::string& alias); + static std::vector> load(const std::string& fieldName, int fieldValue); static std::vector> listAll(); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } + inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } + inline Poco::AutoPtr getHederaId() { return mHederaID; } protected: HederaAccount(model::table::HederaAccount* dbModel); + Poco::AutoPtr mHederaID; }; } diff --git a/src/cpp/controller/NodeServer.cpp b/src/cpp/controller/NodeServer.cpp new file mode 100644 index 000000000..6096b2839 --- /dev/null +++ b/src/cpp/controller/NodeServer.cpp @@ -0,0 +1,145 @@ +#include "NodeServer.h" +#include "../SingletonManager/ErrorManager.h" +#include "../SingletonManager/ConnectionManager.h" + +namespace controller { + + + NodeServer::NodeServer(model::table::NodeServer* dbModel) + { + mDBModel = dbModel; + } + + NodeServer::~NodeServer() + { + + } + + Poco::AutoPtr NodeServer::create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId) + { + auto db = new model::table::NodeServer(url, port, groupId, type, nodeHederaId); + auto group = new NodeServer(db); + return Poco::AutoPtr(group); + } + + std::vector> NodeServer::load(model::table::NodeServerType type, int group_id/* = 0*/) + { + auto db = new model::table::NodeServer(); + std::vector node_server_list; + + if (type == model::table::NODE_SERVER_HEDERA_MAINNET_NODE || type == model::table::NODE_SERVER_HEDERA_TESTNET_NODE) + { + node_server_list = db->loadFromDB("server_type", type, 4); + } + else if (type == model::table::NODE_SERVER_GRADIDO_NODE) + { + if (group_id) + { + node_server_list = db->loadFromDB( + { "server_type", "group_id" }, + { type, group_id }, + model::table::MYSQL_CONDITION_AND + ); + } + else + { + node_server_list = db->loadFromDB("server_type", type, 4); + } + } + //auto node_server_list = db->loadFromDB("alias", alias, 0); + + std::vector> resultVector; + resultVector.reserve(node_server_list.size()); + for (auto it = node_server_list.begin(); it != node_server_list.end(); it++) { + resultVector.push_back(new NodeServer(new model::table::NodeServer(*it))); + } + return resultVector; + } + + /* + SELECT * FROM table_name + ORDER BY RAND() + LIMIT 1; + */ + NodeServerConnection NodeServer::pick(model::table::NodeServerType type, int group_id/* = 0*/) + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + NodeServerConnection result; + int hedera_node_id = 0; + + Poco::Data::Statement select(session); + select << "SELECT url, port"; + + if (model::table::NodeServerIsHederaNode(type)) { + select << ", node_hedera_id"; + } + select << " from node_servers ORDER BY RAND() LIMIT 1" + , Poco::Data::Keywords::into(result.url) + , Poco::Data::Keywords::into(result.port); + if (model::table::NodeServerIsHederaNode(type)) { + select, Poco::Data::Keywords::into(hedera_node_id); + } + try { + if (1 == select.execute()) { + if (model::table::NodeServerIsHederaNode(type)) { + result.hederaId = controller::HederaId::load(hedera_node_id); + } + return result; + } + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + const char* functionName = "NodeServer::pick"; + em->addError(new ParamError(functionName, "mysql error by pick: ", ex.message())); + em->addError(new ParamError(functionName, "server type: ", model::table::NodeServer::nodeServerTypeToString(type))); + em->addError(new ParamError(functionName, "group id", group_id)); + em->sendErrorsAsEmail(); + } + return result; + + } + + std::vector> NodeServer::listAll() + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); + std::vector rows; + // typedef Poco::Tuple NodeServerFullTuple; + select << "SELECT n.id, n.url, n.port, n.group_id, n.server_type, n.node_hedera_id, h.shardNum, h.realmNum, h.num, n.last_live_sign " + << "FROM node_servers as n " + << "LEFT JOIN hedera_ids as h ON h.id = n.node_hedera_id" + , Poco::Data::Keywords::into(rows); + + try { + select.executeAsync(); + select.wait(); + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + const char* functionName = "NodeServer::listAll"; + em->addError(new ParamError(functionName, "mysql error by list all: ", ex.message())); + em->sendErrorsAsEmail(); + } + std::vector> results; + for (auto it = rows.begin(); it != rows.end(); it++) { + //NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId); + auto row = *it; + model::table::NodeServer* db = new model::table::NodeServer( + row.get<1>(), row.get<2>(), row.get<3>(), (model::table::NodeServerType)row.get<4>(), row.get<5>() + ); + db->setLastLiveSign(row.get<9>()); + db->setID(row.get<0>()); + Poco::AutoPtr node_server(new NodeServer(db)); + node_server->setHederaId(controller::HederaId::create( + row.get<6>(), row.get<7>(), row.get<8>() + )); + results.push_back(node_server); + + } + return results; + + } + +} \ No newline at end of file diff --git a/src/cpp/controller/NodeServer.h b/src/cpp/controller/NodeServer.h new file mode 100644 index 000000000..5a2750194 --- /dev/null +++ b/src/cpp/controller/NodeServer.h @@ -0,0 +1,52 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE + +#include "../model/table/NodeServer.h" +#include "../controller/HederaId.h" + +#include "Poco/SharedPtr.h" + +#include "TableControllerBase.h" + +namespace controller { + + struct NodeServerConnection + { + NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {} + NodeServerConnection() :port(0) {}; + + bool isValid() { return url != "" && port; } + std::string url; + int port; + + Poco::AutoPtr hederaId; + }; + + typedef Poco::Tuple NodeServerFullTuple; + + class NodeServer : public TableControllerBase + { + public: + + ~NodeServer(); + + static Poco::AutoPtr create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId); + + static std::vector> load(model::table::NodeServerType type, int group_id = 0); + static std::vector> listAll(); + // pick server randomly + NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0); + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } + inline Poco::AutoPtr getHederaId() { return mHederaID; } + protected: + NodeServer(model::table::NodeServer* dbModel); + Poco::AutoPtr mHederaID; + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 2219fc521..c38af1df1 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -29,6 +29,15 @@ namespace model { static const char* hederaNetworkTypeToString(HederaNetworkType type); + inline int getAccountHederaId() { return mAccountHederaId; } + + inline Poco::UInt64 getBalance() { return mBalance; } + inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } + + inline HederaNetworkType getNetworkType() { return (HederaNetworkType)mType; } + + inline std::string getUpdatedString() { return Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S"); } + protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index a4f25cc78..9f26f05c5 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -24,12 +24,37 @@ namespace model { std::string HederaId::toString() { std::stringstream ss; - ss << "Shard Num: " << std::to_string(mShardNum) << std::endl; - ss << "Realm Num: " << std::to_string(mRealmNum) << std::endl; - ss << "Num: " << std::to_string(mNum) << std::endl; + ss << std::to_string(mShardNum) << "." << std::to_string(mRealmNum) << "." << std::to_string(mNum) << std::endl; return ss.str(); } + int HederaId::getID() + { + auto cm = ConnectionManager::getInstance(); + Poco::ScopedLock _lock(mWorkMutex); + + assert(mNum != 0|| mShardNum != 0 || mRealmNum != 0); + if (mID) return mID; + + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); + select << "SELECT id FROM " << getTableName() + << " where shardNum = ? AND realmNum = ? AND num = ?" + , into(mID), use(mShardNum), use(mRealmNum), use(mNum); + + try { + if (1 == select.execute()) { + return mID; + } + } + catch (Poco::Exception& ex) { + addError(new ParamError("HederaId::getID", "mysql error try to find existing entry", ex.message())); + sendErrorsAsEmail(); + } + insertIntoDB(true); + return mID; + } + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index c36d1f656..8de69c2a9 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -18,6 +18,9 @@ namespace model { const char* getTableName() const { return "hedera_ids"; } std::string toString(); + //! \brief check if hedera id already in db, then return id, else insert in db and return + int getID(); + protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index 5dfb709fb..7bb7301f6 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -48,17 +48,22 @@ namespace model { size_t resultCount = 0; try { - if (insert.execute() == 1) { + if (insert.execute(true) == 1) { // load id from db if (loadId) { - Poco::Data::Statement select = _loadIdFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + Poco::Data::Statement select = _loadIdFromDB(session); try { - return select.execute() == 1; + select.executeAsync(); + return select.wait() == 1; } catch (Poco::Exception& ex) { addError(new ParamError(getTableName(), "mysql error by select id", ex.displayText().data())); addError(new ParamError(getTableName(), "data set: ", toString().data())); } + select.reset(session); + select = _loadIdFromDB(session); + //Poco::Data::Statement select = _loadIdFromDB(session); + select.execute(); } else { return true; diff --git a/src/cpp/model/table/NodeServer.cpp b/src/cpp/model/table/NodeServer.cpp new file mode 100644 index 000000000..ae3bdbf81 --- /dev/null +++ b/src/cpp/model/table/NodeServer.cpp @@ -0,0 +1,114 @@ + +#include "NodeServer.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + + bool NodeServerIsHederaNode(NodeServerType type) { + return type == NODE_SERVER_HEDERA_MAINNET_NODE || type == NODE_SERVER_HEDERA_TESTNET_NODE; + } + bool NodeServerHasGroup(NodeServerType type) { + return type == NODE_SERVER_GRADIDO_NODE || type == NODE_SERVER_GRADIDO_COMMUNITY; + } + + + NodeServer::NodeServer() + : mPort(0), mGroupId(0), mServerType(0), mNodeHederaId(0) + { + + } + + NodeServer::NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId) + : mUrl(url), mPort(port), mGroupId(groupId), mServerType(type), mNodeHederaId(nodeHederaId) + { + } + + + + NodeServer::NodeServer(const NodeServerTuple& tuple) + : ModelBase(tuple.get<0>()), + mUrl(tuple.get<1>()), mPort(tuple.get<2>()), mGroupId(tuple.get<3>()), + mServerType(tuple.get<4>()), mNodeHederaId(tuple.get<5>()), mLastLiveSign(tuple.get<6>()) + { + + } + + NodeServer::~NodeServer() + { + + } + + std::string NodeServer::toString() + { + std::stringstream ss; + + ss << "id: " << getID() << std::endl; + ss << mUrl << ":" << mPort << std::endl; + ss << "group id: " << mGroupId << std::endl; + ss << "server type: " << nodeServerTypeToString((NodeServerType)mServerType) << std::endl; + ss << "node hedera id: " << mNodeHederaId << std::endl; + ss << "last live sign: " << Poco::DateTimeFormatter::format(mLastLiveSign, "%f.%m.%Y %H:%M:%S") << std::endl; + + return ss.str(); + } + + const char* NodeServer::nodeServerTypeToString(NodeServerType type) + { + switch (type) { + case NODE_SERVER_NONE: return "none"; + case NODE_SERVER_GRADIDO_NODE: return "Gradido Node"; + case NODE_SERVER_GRADIDO_COMMUNITY: return "Gradido Community"; + case NODE_SERVER_HEDERA_MAINNET_NODE: return "Hedera Mainnet Node"; + case NODE_SERVER_HEDERA_TESTNET_NODE: return "Hedera Testnet Node"; + default: return ""; + } + } + + Poco::Data::Statement NodeServer::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mUrl), into(mPort), into(mGroupId), into(mServerType), into(mNodeHederaId), into(mLastLiveSign); + + return select; + } + + Poco::Data::Statement NodeServer::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + // typedef Poco::Tuple, int> UserTuple; + select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName() + << " where " << fieldName << " LIKE ?"; + + return select; + } + + Poco::Data::Statement NodeServer::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + lock(); + select << "SELECT id FROM " << getTableName() + << " where url = ? AND port = ? " + , into(mID), use(mUrl), use(mPort); + + unlock(); + return select; + } + + Poco::Data::Statement NodeServer::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + lock(); + insert << "INSERT INTO " << getTableName() + << " (url, port, group_id, server_type, node_hedera_id) VALUES(?,?,?,?,?)" + , use(mUrl), use(mPort), use(mGroupId), use(mServerType), use(mNodeHederaId); + unlock(); + return insert; + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/table/NodeServer.h b/src/cpp/model/table/NodeServer.h new file mode 100644 index 000000000..899be9196 --- /dev/null +++ b/src/cpp/model/table/NodeServer.h @@ -0,0 +1,71 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE + +#include "ModelBase.h" +#include "Poco/Tuple.h" + +namespace model { + namespace table { + + typedef Poco::Tuple NodeServerTuple; + + enum NodeServerType { + NODE_SERVER_NONE, + NODE_SERVER_GRADIDO_NODE, + NODE_SERVER_GRADIDO_COMMUNITY, + NODE_SERVER_HEDERA_MAINNET_NODE, + NODE_SERVER_HEDERA_TESTNET_NODE, + NODE_SERVER_TYPE_COUNT + }; + bool NodeServerIsHederaNode(NodeServerType type); + bool NodeServerHasGroup(NodeServerType type); + + + class NodeServer : public ModelBase + { + public: + NodeServer(); + NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId); + NodeServer(const NodeServerTuple& tuple); + ~NodeServer(); + + // generic db operations + const char* getTableName() const { return "node_servers"; } + std::string toString(); + + static const char* nodeServerTypeToString(NodeServerType type); + + inline void setLastLiveSign(Poco::DateTime lastLiveSign) { std::unique_lock _lock(mSharedMutex); mLastLiveSign = lastLiveSign; } + + inline std::string getUrl() const { return mUrl; } + inline int getPort() const { return mPort; } + inline std::string getUrlWithPort() const { return mUrl + ":" + std::to_string(mPort); } + inline int getGroupId() const { return mGroupId; } + inline NodeServerType getNodeServerType() const { return (NodeServerType)mServerType; } + inline bool isHederaNode() const { return NodeServerIsHederaNode((NodeServerType)mServerType);} + inline bool hasGroup() const {return NodeServerHasGroup((NodeServerType)mServerType);} + inline int getNodeHederaId() const { return mNodeHederaId; } + inline Poco::DateTime getLastLiveSign() const { std::shared_lock _lock(mSharedMutex); return mLastLiveSign; } + + protected: + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName); + Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + std::string mUrl; + int mPort; + int mGroupId; + int mServerType; + int mNodeHederaId; + Poco::DateTime mLastLiveSign; + + mutable std::shared_mutex mSharedMutex; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE \ No newline at end of file diff --git a/src/cpsp/adminGroups.cpsp b/src/cpsp/adminGroups.cpsp index e357388af..014591b74 100644 --- a/src/cpsp/adminGroups.cpsp +++ b/src/cpsp/adminGroups.cpsp @@ -34,7 +34,7 @@ //auto groups = controller::Group::load("gdd1"); //std::vector> groups; -%><%@ include file="header.cpsp" %> +%><%@ include file="header_large.cpsp" %> <%= getErrorsHtml() %>
    @@ -43,20 +43,20 @@
    -
    ID
    -
    Name
    -
    Alias
    -
    Url
    -
    <%= gettext("Description") %>
    +
    ID
    +
    Name
    +
    Alias
    +
    Url
    +
    <%= gettext("Description") %>
    <% for(auto it = groups.begin(); it != groups.end(); it++) { auto group_model = (*it)->getModel(); %>
    -
    <%= group_model->getID() %>
    -
    <%= group_model->getName() %>
    -
    <%= group_model->getAlias() %>
    -
    <%= group_model->getUrl() %>
    -
    <%= group_model->getDescription()%>
    +
    <%= group_model->getID() %>
    +
    <%= group_model->getName() %>
    +
    <%= group_model->getAlias() %>
    +
    <%= group_model->getUrl() %>
    +
    <%= group_model->getDescription()%>
    <% } %>
    diff --git a/src/cpsp/adminNodeServer.cpsp b/src/cpsp/adminNodeServer.cpsp new file mode 100644 index 000000000..e4a0ff49d --- /dev/null +++ b/src/cpsp/adminNodeServer.cpsp @@ -0,0 +1,200 @@ +<%@ page class="AdminNodeServerPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + +#include "../controller/NodeServer.h" +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" +#include "../lib/DataTypeConverter.h" + +%> +<%% + const char* pageName = "Node Server"; + auto sm = SessionManager::getInstance(); + + // add + if(!form.empty()) { + // collect + auto url = form.get("node-server-url", ""); + auto portString = form.get("node-server-port", ""); + auto nodeServerTypeString = form.get("node-server-type", "0"); + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto nodeServerGroupString = form.get("node-server-group", ""); + + int port = 0; + int shardNum = 0; + int realmNum = 0; + int num = 0; + model::table::NodeServerType nodeServerType = model::table::NODE_SERVER_NONE; + int group_id = 0; + + + // validate + if(!sm->isValid(url, VALIDATE_ONLY_URL)) { + addError(new ParamError("Node Server", "Url not valid, must start with http or https", url)); + + } + if(!sm->isValid(portString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server", "Port isn't valid integer")); + } else { + if(DataTypeConverter::strToInt(portString, port) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting port to int")); + } + } + + if(!sm->isValid(nodeServerTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Node Server Type", "not integer")); + } else { + int node_server_type_int = 0; + if(DataTypeConverter::strToInt(nodeServerTypeString, node_server_type_int) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting node server type to int")); + } + if(node_server_type_int < 0 || node_server_type_int >= (int)model::table::NODE_SERVER_TYPE_COUNT) { + addError(new Error("Node Server Type", "invalid value")); + } else { + nodeServerType = (model::table::NodeServerType)node_server_type_int; + } + } + if(model::table::NodeServerIsHederaNode(nodeServerType)) { + + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + } else if(model::table::NodeServerHasGroup(nodeServerType)) { + if(!sm->isValid(nodeServerGroupString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(nodeServerGroupString, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } + } + + + + if(0 == errorCount()) { + int hedera_id_int = 0; + if(NodeServerIsHederaNode(nodeServerType)) { + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + hedera_id_int = hedera_id->getModel()->getID(); + } + + auto node_server = controller::NodeServer::create( + url, port, group_id, (model::table::NodeServerType)nodeServerType, hedera_id_int + ); + if(!node_server->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving Node Server in DB")); + } + } + } + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } + + auto node_servers = controller::NodeServer::listAll(); + + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
    +
    +
    +

    Alle Node Server

    +
    +
    +
    +
    Server Type
    +
    Url:Port
    +
    Group / Hedera Id
    +
    + <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { + auto node_server_model = (*it)->getModel(); + %> +
    +
    <%= model::table::NodeServer::nodeServerTypeToString(node_server_model->getNodeServerType()) %>
    +
    <%= node_server_model->getUrlWithPort() %>
    +
    + <% if(node_server_model->isHederaNode()) { + auto hedera_id_model = (*it)->getHederaId()->getModel(); %> + <%= hedera_id_model->toString() %> + <% } else if(node_server_model->hasGroup()){ + auto groupIt = group_indices.find(node_server_model->getGroupId()); + if(groupIt != group_indices.end()) { + auto group_model = groups[groupIt->second]->getModel(); %> + <%= group_model->getName() %> + <% } else { %> + <%= node_server_model->getGroupId() %> + <% } %> + <% } %> +
    +
    + <% } %> +
    +
    +
    +

    Ein Node Server hinzufügen

    +
    +
    +
    + + + + + + +
    + Nur für Hedera Nodes + + + + +
    +
    + Nur für Gradido Nodes + + +
    + + "> +
    +
    + +<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/header_large.cpsp b/src/cpsp/header_large.cpsp index 2aa8f5f4b..5f7a8a021 100644 --- a/src/cpsp/header_large.cpsp +++ b/src/cpsp/header_large.cpsp @@ -16,4 +16,14 @@
    +
    \ No newline at end of file From a06cfebd60b824747c0a7533caa3892f361d362c Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 31 Aug 2020 15:05:54 +0200 Subject: [PATCH 065/195] add function to crypto key controller to get directly a KeyPairHedera --- src/cpp/Crypto/KeyPairHedera.cpp | 22 +++++++++++++--------- src/cpp/Crypto/KeyPairHedera.h | 1 + src/cpp/controller/CryptoKey.cpp | 17 +++++++++++++++++ src/cpp/controller/CryptoKey.h | 2 ++ src/cpp/model/table/CryptoKey.h | 5 +++++ 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 0a3bf4bc2..2846e9c43 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -10,13 +10,12 @@ KeyPairHedera::KeyPairHedera() } - -KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) +KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) : mPrivateKey(nullptr) { auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420"); - auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100"); - + auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100"); + auto mm = MemoryManager::getInstance(); if (privateKey) { @@ -46,19 +45,19 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi default: throw std::exception("[KeyPairHedera] invalid private key"); } - + // check public } if (publicKey) { - switch (publicKey->size()) + switch (publicKeySize) { case 32: { // raw public key - memcpy(mPublicKey, *publicKey, publicKey->size()); + memcpy(mPublicKey, publicKey, publicKeySize); break; } case 44: // DER encoded public key - if (0 == sodium_memcmp(*publicKey, *derPrefixPub, derPrefixPub->size())) { - memcpy(mPublicKey, publicKey->data(derPrefixPub->size()), ed25519_pubkey_SIZE); + if (0 == sodium_memcmp(publicKey, *derPrefixPub, derPrefixPub->size())) { + memcpy(mPublicKey, &publicKey[derPrefixPub->size()], ed25519_pubkey_SIZE); } break; default: @@ -75,6 +74,11 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publi mm->releaseMemory(derPrefixPriv); mm->releaseMemory(derPrefixPub); } +KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) + : KeyPairHedera(privateKey, publicKey->data(), publicKey->size()) +{ + +} KeyPairHedera::~KeyPairHedera() { diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 115beebdb..7f0b7f3bc 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -22,6 +22,7 @@ public: //! \param privateKey: copy //! \param publicKey: copy //! + KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); ~KeyPairHedera(); diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 2e7d343ec..093a21e69 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -62,6 +62,23 @@ namespace controller { return nullptr; } + KeyPairHedera* CryptoKey::getKeyPair(Poco::AutoPtr user) + { + auto model = getModel(); + auto password = user->getPassword(); + auto mm = MemoryManager::getInstance(); + if (!password || !model->hasPrivateKeyEncrypted()) { + return nullptr; + } + MemoryBin* clearPassword = nullptr; + if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { + return nullptr; + } + KeyPairHedera* key_pair = new KeyPairHedera(clearPassword, model->getPublicKey(), model->getPublicKeySize()); + mm->releaseMemory(clearPassword); + return key_pair; + } + } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index 6e4e110bb..12bb40e70 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -27,6 +27,8 @@ namespace controller { inline Poco::AutoPtr getModel() { return _getModel(); } + KeyPairHedera* getKeyPair(Poco::AutoPtr user); + protected: CryptoKey(model::table::CryptoKey* dbModel); diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index 58d6df5dc..7e50fc728 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -24,6 +24,11 @@ namespace model { const char* getTableName() const { return "crypto_keys"; } std::string toString(); + inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } + + inline bool hasPrivateKeyEncrypted() const { return !mPrivateKey.isNull(); } + inline const std::vector& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); } static const char* typeToString(KeyType type); protected: From 2e842fab0dcc4f82b1a86a12c4eb68e6c2483a03 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 31 Aug 2020 19:55:56 +0200 Subject: [PATCH 066/195] compose hedera query to get balance, update CMakeLists.txt for adding missing libs for grpc --- CMakeLists.txt | 27 +++- src/cpp/Crypto/KeyPairHedera.h | 1 + .../HTTPInterface/AdminHederaAccountPage.cpp | 68 +++++++--- src/cpp/controller/CryptoKey.cpp | 6 +- src/cpp/controller/CryptoKey.h | 2 +- src/cpp/controller/HederaAccount.cpp | 37 ++++++ src/cpp/controller/HederaAccount.h | 5 +- src/cpp/controller/HederaId.cpp | 8 ++ src/cpp/controller/HederaId.h | 5 + src/cpp/controller/NodeServer.h | 4 +- src/cpp/main.cpp | 116 +++++++++--------- src/cpp/model/hedera/Query.cpp | 83 +++++++++++++ src/cpp/model/hedera/Query.h | 39 ++++++ src/cpp/model/table/HederaAccount.cpp | 9 ++ src/cpp/model/table/HederaAccount.h | 9 +- src/cpp/model/table/HederaId.h | 4 + src/cpp/model/table/NodeServer.h | 3 +- 17 files changed, 346 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc8b2fe4c..52f79bdc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,9 +95,30 @@ find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-conne find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build/Debug" REQUIRED) set(GRPC_PATH "dependencies/grpc/_build/Debug") +set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/Debug") +set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") +set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) -set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION}) +find_library(GRPC_LIB grpc PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_ERROR_DETAILS grpc++_error_details PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) + +find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) +set(GRPC_LIBS + ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} + ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} + ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} + ${GRPC_CARES} ${GRPC_BORING_SSL_CRYPTO} ${GRPC_BORING_SSL_SSL} +) + set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") #set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") @@ -142,7 +163,9 @@ include_directories( endif(WIN32) -target_link_libraries(Gradido_LoginServer ${CONAN_LIBS} ${IROHA_ED25519}) +add_subdirectory("dependencies/grpc/third_party/abseil-cpp") + +target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 7f0b7f3bc..a3e4337e5 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -37,6 +37,7 @@ public: inline const unsigned char* getPublicKey() const { return mPublicKey; } MemoryBin* getPublicKeyCopy() const; + const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;} inline bool isTheSame(const KeyPairHedera& b) const { return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 0de7a6922..0169083ef 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -14,6 +14,10 @@ #include "../lib/DataTypeConverter.h" #include "../SingletonManager/SessionManager.h" +#include "../ServerConfig.h" + +#include "Poco/URI.h" + #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" #include "../ServerConfig.h" @@ -33,15 +37,42 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 20 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Poco::URI uri(request.getURI()); + auto uri_query = uri.getQueryParameters(); + std::string action = ""; + std::string account_id_from_query; + if(uri_query[0].first == "action") { + action = uri_query[0].second; + } + if(uri_query[1].first == "account_id") { + account_id_from_query = uri_query[1].second; + } + for(auto it = uri_query.begin(); it != uri_query.end(); it++) { + printf("first: %s, second: %s\n", it->first.data(), it->second.data()); + } + + if(action == "updateBalance") { + int account_id = 0; + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); + } else { + auto hedera_account = controller::HederaAccount::load("id", account_id); + if(!hedera_account.size() || hedera_account[0].isNull()) { + addError(new Error("Action Update Balance", "hedera id not found")); + } else { + hedera_account[0]->updateBalanceFromHedera(user); + } + } + } // add - if(!form.empty()) { + else if(!form.empty()) { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); @@ -196,7 +227,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -210,32 +241,41 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Balance
    \n"; responseStream << "\t\t\t\t
    Server Type
    \n"; responseStream << "\t\t\t\t
    Last Updated
    \n"; + responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 134 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); + auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 140 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 173 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 141 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -255,21 +295,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 093a21e69..3fabc25c5 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -62,19 +62,21 @@ namespace controller { return nullptr; } - KeyPairHedera* CryptoKey::getKeyPair(Poco::AutoPtr user) + std::unique_ptr CryptoKey::getKeyPair(Poco::AutoPtr user) { auto model = getModel(); auto password = user->getPassword(); auto mm = MemoryManager::getInstance(); if (!password || !model->hasPrivateKeyEncrypted()) { + printf("[CryptoKey::getKeyPair] return null, password empty or no private key\n"); return nullptr; } MemoryBin* clearPassword = nullptr; if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { + printf("[CryptoKey::getKeyPair] return null, error decrypting\n"); return nullptr; } - KeyPairHedera* key_pair = new KeyPairHedera(clearPassword, model->getPublicKey(), model->getPublicKeySize()); + auto key_pair = std::make_unique(clearPassword, model->getPublicKey(), model->getPublicKeySize()); mm->releaseMemory(clearPassword); return key_pair; } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index 12bb40e70..fc69d042c 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -27,7 +27,7 @@ namespace controller { inline Poco::AutoPtr getModel() { return _getModel(); } - KeyPairHedera* getKeyPair(Poco::AutoPtr user); + std::unique_ptr getKeyPair(Poco::AutoPtr user); protected: diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 9f4ff5b40..564752f72 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -1,5 +1,9 @@ #include "HederaAccount.h" +#include "NodeServer.h" +#include "CryptoKey.h" +#include "../model/hedera/Query.h" +#include "HederaRequest.h" namespace controller { @@ -69,5 +73,38 @@ namespace controller { return resultVector; } + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user) + { + static const char* functionName = "HederaAccount::updateBalanceFromHedera"; + + if (user.isNull() || !user->getModel()) { + printf("[%s] invalid user\n", functionName); + return false; + } + + auto account_model = getModel(); + auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); + auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); + if (crypto_key.isNull()) { + printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); + return false; + } + auto hedera_key_pair = crypto_key->getKeyPair(user); + if (!hedera_key_pair) { + printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); + return false; + } + auto query = model::hedera::Query::getBalance(mHederaID, hedera_node); + if (!query) { + printf("[%s] error creating query\n", functionName); + } + query->sign(std::move(hedera_key_pair)); + + HederaRequest request; + request.request(query); + + return false; + } + } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index dd4c97435..1a3fd9ace 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -1,7 +1,8 @@ #ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE #define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE -#include "../controller/HederaId.h" +#include "HederaId.h" +#include "User.h" #include "../model/table/HederaAccount.h" #include "Poco/SharedPtr.h" @@ -26,6 +27,8 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } + bool updateBalanceFromHedera(Poco::AutoPtr user); + protected: HederaAccount(model::table::HederaAccount* dbModel); Poco::AutoPtr mHederaID; diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index e6d281907..ce171a7a8 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -29,4 +29,12 @@ namespace controller { } return nullptr; } + + void HederaId::copyToProtoAccountId(proto::AccountID* protoAccountId) const + { + auto model = getModel(); + protoAccountId->set_shardnum(model->getShardNum()); + protoAccountId->set_realmnum(model->getRealmNum()); + protoAccountId->set_accountnum(model->getNum()); + } } \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index f02e69373..ae9296a43 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -7,6 +7,8 @@ #include "TableControllerBase.h" +#include "../proto/hedera/BasicTypes.pb.h" + namespace controller { class HederaId : public TableControllerBase { @@ -21,6 +23,9 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::HederaId* getModel() const { return _getModel(); } + + void copyToProtoAccountId(proto::AccountID* protoAccountId) const; protected: diff --git a/src/cpp/controller/NodeServer.h b/src/cpp/controller/NodeServer.h index 5a2750194..8cc4b4e23 100644 --- a/src/cpp/controller/NodeServer.h +++ b/src/cpp/controller/NodeServer.h @@ -15,6 +15,8 @@ namespace controller { NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {} NodeServerConnection() :port(0) {}; + std::string getUrlWithPort() const { return url + ":" + std::to_string(port); } + bool isValid() { return url != "" && port; } std::string url; int port; @@ -35,7 +37,7 @@ namespace controller { static std::vector> load(model::table::NodeServerType type, int group_id = 0); static std::vector> listAll(); // pick server randomly - NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0); + static NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index be08da820..910db09ff 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -1,57 +1,61 @@ -#include "Gradido_LoginServer.h" -#include - -#include "proto/gradido/TransactionBody.pb.h" - -#include "model/User.h" -#include "model/Session.h" -#include "lib/Profiler.h" -#include "ServerConfig.h" -#include "ImportantTests.h" - -#include "model/table/User.h" -#include "model/table/EmailOptIn.h" - -#include "Poco/DateTimeParser.h" - -#ifndef _TEST_BUILD - - -int main(int argc, char** argv) -{ - GOOGLE_PROTOBUF_VERIFY_VERSION; - if (sodium_init() < 0) { - /* panic! the library couldn't be initialized, it is not safe to use */ - printf("error initializing sodium, early exit\n"); - return -1; - } - - std::string dateTimeString = __DATE__; - //printf("Building date time string: %s\n", dateTimeString.data()); - std::string formatString("%b %d %Y"); - int timeZone = 0; - - Poco::DateTime buildDateTime = Poco::DateTimeParser::parse(formatString, dateTimeString, timeZone); - ServerConfig::g_versionString = Poco::DateTimeFormatter::format(buildDateTime, "0.%y.%m.%d"); - //ServerConfig::g_versionString = "0.20.KW13.02"; - printf("Version: %s\n", ServerConfig::g_versionString.data()); - printf("User size: %d Bytes, Session size: %d Bytes\n", sizeof(User), sizeof(Session)); - printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", sizeof(model::table::User), sizeof(model::table::EmailOptIn)); - - // load word lists - if (!ServerConfig::loadMnemonicWordLists()) { - //printf("[Gradido_LoginServer::%s] error loading mnemonic Word List\n", __FUNCTION__); - printf("[Gradido_LoginServer::main] error loading mnemonic Word List"); - return -2; - } - - if (!ImportantTests::passphraseGenerationAndTransformation()) { - printf("test passphrase generation and transformation failed\n"); - return -3; - } - - Gradido_LoginServer app; - app.setUnixOptions(true); - return app.run(argc, argv); -} +#include "Gradido_LoginServer.h" +#include + +#include "proto/gradido/TransactionBody.pb.h" + +#include "model/User.h" +#include "model/Session.h" +#include "lib/Profiler.h" +#include "ServerConfig.h" +#include "ImportantTests.h" + +#include "model/table/User.h" +#include "model/table/EmailOptIn.h" + +#include "Poco/DateTimeParser.h" +#include + +#ifndef _TEST_BUILD + + +int main(int argc, char** argv) +{ + GOOGLE_PROTOBUF_VERIFY_VERSION; + if (sodium_init() < 0) { + /* panic! the library couldn't be initialized, it is not safe to use */ + printf("error initializing sodium, early exit\n"); + return -1; + } + + std::string dateTimeString = __DATE__; + //printf("Building date time string: %s\n", dateTimeString.data()); + std::string formatString("%b %d %Y"); + int timeZone = 0; + + Poco::DateTime buildDateTime = Poco::DateTimeParser::parse(formatString, dateTimeString, timeZone); + ServerConfig::g_versionString = Poco::DateTimeFormatter::format(buildDateTime, "0.%y.%m.%d"); + //ServerConfig::g_versionString = "0.20.KW13.02"; + printf("Version: %s\n", ServerConfig::g_versionString.data()); + printf("User size: %d Bytes, Session size: %d Bytes\n", (int)sizeof(User), (int)sizeof(Session)); + printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", (int)sizeof(model::table::User), (int)sizeof(model::table::EmailOptIn)); + + // load word lists + if (!ServerConfig::loadMnemonicWordLists()) { + //printf("[Gradido_LoginServer::%s] error loading mnemonic Word List\n", __FUNCTION__); + printf("[Gradido_LoginServer::main] error loading mnemonic Word List"); + return -2; + } + + if (!ImportantTests::passphraseGenerationAndTransformation()) { + printf("test passphrase generation and transformation failed\n"); + return -3; + } + grpc_init(); + + Gradido_LoginServer app; + auto result = app.run(argc, argv); + + grpc_shutdown(); + return result; +} #endif \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index e69de29bb..d47449bc6 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -0,0 +1,83 @@ +#include "Query.h" +#include "Poco/Timestamp.h" +#include "../../SingletonManager/MemoryManager.h" + +namespace model { + namespace hedera { + + Query::Query(const controller::NodeServerConnection& connection) + : mConnection(connection) + { + + } + + Query::~Query() + { + + } + + Query* Query::getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection) + { + + assert(!accountId.isNull() && accountId->getModel()); + + auto query = new Query(connection); + auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance(); + accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); + auto query_header = get_account_balance->mutable_header(); + query_header->set_responsetype(proto::ANSWER_ONLY); + auto transaction = query_header->mutable_payment(); + //auto transaction_body = transaction->mutable_body(); + // body content + // transaction id + auto transaction_id = query->mTransactionBody.mutable_transactionid(); + auto timestamp = transaction_id->mutable_transactionvalidstart(); + Poco::Timestamp now; + auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 + timestamp->set_seconds(now.epochTime()); + timestamp->set_nanos(microseconds * 1000); + accountId->copyToProtoAccountId(transaction_id->mutable_accountid()); + // + // sdk default, but can be changed + query->mTransactionBody.set_transactionfee(100000000); + auto valid_duration = query->mTransactionBody.mutable_transactionvalidduration(); + // maximal 2 minutes + valid_duration->set_seconds(120); + auto crypto_transfer = query->mTransactionBody.mutable_cryptotransfer(); + auto transfer_list = crypto_transfer->mutable_transfers(); + auto account_amounts = transfer_list->mutable_accountamounts(); + account_amounts->Add(); + auto account_amount = account_amounts->Mutable(0); + account_amount->set_amount(0); + connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); + + return query; + } + + bool Query::sign(std::unique_ptr keyPairHedera) + { + auto mm = MemoryManager::getInstance(); + auto body_bytes = mTransactionBody.SerializeAsString(); + auto transaction = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header()->mutable_payment(); + transaction->set_bodybytes(body_bytes.data()); + auto signature_map = transaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_pairs->Add(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + + return true; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index e69de29bb..8dff35024 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -0,0 +1,39 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H + +/*! + * @author: Dario Rekowski + * + * @date: 31.08.20 + * + * @brief: class for put together hedera querys (ask for state data, not a transaction, but needs a payment transaction) + * +*/ + +#include "../../proto/hedera/Query.pb.h" +#include "../../controller/NodeServer.h" +#include "../../Crypto/KeyPairHedera.h" + +namespace model { + namespace hedera { + class Query + { + public: + ~Query(); + static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); + bool sign(std::unique_ptr keyPairHedera); + + inline const proto::Query* getProtoQuery() const { return &mQueryProto; } + inline std::string getConnectionString() const { return mConnection.getUrlWithPort(); } + + protected: + Query(const controller::NodeServerConnection& connection); + proto::Query mQueryProto; + proto::TransactionBody mTransactionBody; + controller::NodeServerConnection mConnection; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H \ No newline at end of file diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 06538fdcb..1485ff554 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -53,6 +53,15 @@ namespace model { } } + NodeServerType HederaAccount::networkTypeToNodeServerType(HederaNetworkType type) + { + switch (type) { + case HEDERA_MAINNET: return NODE_SERVER_HEDERA_MAINNET_NODE; + case HEDERA_TESTNET: return NODE_SERVER_HEDERA_TESTNET_NODE; + default: return NODE_SERVER_TYPE_NONE; + } + } + Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index c38af1df1..4d4dd6575 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -4,6 +4,8 @@ #include "ModelBase.h" #include "Poco/Tuple.h" +#include "NodeServer.h" + namespace model { namespace table { @@ -12,7 +14,7 @@ namespace model { enum HederaNetworkType { HEDERA_MAINNET, HEDERA_TESTNET, - HEDERA_NET_COUNT + HEDERA_NET_COUNT, }; class HederaAccount : public ModelBase @@ -28,13 +30,16 @@ namespace model { std::string toString(); static const char* hederaNetworkTypeToString(HederaNetworkType type); + static NodeServerType networkTypeToNodeServerType(HederaNetworkType type); - inline int getAccountHederaId() { return mAccountHederaId; } + inline int getAccountHederaId() const { return mAccountHederaId; } + inline int getCryptoKeyId() const { return mAccountKeyId; } inline Poco::UInt64 getBalance() { return mBalance; } inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } inline HederaNetworkType getNetworkType() { return (HederaNetworkType)mType; } + inline std::string getUpdatedString() { return Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S"); } diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index 8de69c2a9..9dc2029bc 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -21,6 +21,10 @@ namespace model { //! \brief check if hedera id already in db, then return id, else insert in db and return int getID(); + inline Poco::UInt64 getShardNum() const { return mShardNum; } + inline Poco::UInt64 getRealmNum() const { return mRealmNum; } + inline Poco::UInt64 getNum() const { return mNum; } + protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/NodeServer.h b/src/cpp/model/table/NodeServer.h index 899be9196..4e592c822 100644 --- a/src/cpp/model/table/NodeServer.h +++ b/src/cpp/model/table/NodeServer.h @@ -15,7 +15,8 @@ namespace model { NODE_SERVER_GRADIDO_COMMUNITY, NODE_SERVER_HEDERA_MAINNET_NODE, NODE_SERVER_HEDERA_TESTNET_NODE, - NODE_SERVER_TYPE_COUNT + NODE_SERVER_TYPE_COUNT, + NODE_SERVER_TYPE_NONE }; bool NodeServerIsHederaNode(NodeServerType type); bool NodeServerHasGroup(NodeServerType type); From 2881d33fedcf6e6b78e13972fd5b76915b5e9b52 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:06:20 +0200 Subject: [PATCH 067/195] update grpc to new version, update some things they don't work for create the first query to hedera --- CMakeLists.txt | 7 ++- skeema/gradido_login/crypto_keys.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 5 ++ .../HTTPInterface/AdminHederaAccountPage.cpp | 49 ++++++++++--------- src/cpp/controller/CryptoKey.cpp | 4 ++ src/cpp/controller/HederaAccount.cpp | 12 ++++- src/cpp/controller/HederaAccount.h | 2 +- src/cpp/controller/NodeServer.cpp | 15 +++++- src/cpp/controller/NodeServer.h | 6 ++- src/cpp/lib/DataTypeConverter.h | 1 + src/cpp/model/hedera/Query.h | 2 +- 11 files changed, 73 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52f79bdc1..d679dfd63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ set(GRPC_PATH "dependencies/grpc/_build/Debug") set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/Debug") set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") +set(GRPC_RE2_PATH "dependencies/grpc/_build/third_party/re2/Debug") find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) @@ -110,13 +111,17 @@ find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_RE2 re2 ${GRPC_RE2_PATH} REQUIRED) find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} - ${GRPC_CARES} ${GRPC_BORING_SSL_CRYPTO} ${GRPC_BORING_SSL_SSL} + ${GRPC_CARES} + ${GRPC_BORING_SSL_CRYPTO} + ${GRPC_BORING_SSL_SSL} + ${GRPC_RE2} ) set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index c90750ae3..c79987755 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,6 +1,6 @@ CREATE TABLE `crypto_keys` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `private_key` varbinary(64) NOT NULL, + `private_key` binary(80) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`), diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 2846e9c43..27d9731a7 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -162,8 +162,13 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtrencrypt(mPrivateKey, &encryptedKey)) { + auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encryptedKey); + printf("[KeyPairHedera::getCryptedPrivKey] encryptet private key hex: %s\n", encrypted_private_key_hex_string.data()); return encryptedKey; } else { diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 0169083ef..a9d4165c3 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -48,16 +48,14 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto uri_query = uri.getQueryParameters(); std::string action = ""; std::string account_id_from_query; - if(uri_query[0].first == "action") { - action = uri_query[0].second; + if(uri_query.size() >= 2) { + if(uri_query[0].first == "action") { + action = uri_query[0].second; + } + if(uri_query[1].first == "account_id") { + account_id_from_query = uri_query[1].second; + } } - if(uri_query[1].first == "account_id") { - account_id_from_query = uri_query[1].second; - } - for(auto it = uri_query.begin(); it != uri_query.end(); it++) { - printf("first: %s, second: %s\n", it->first.data(), it->second.data()); - } - if(action == "updateBalance") { int account_id = 0; if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { @@ -67,7 +65,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { - hedera_account[0]->updateBalanceFromHedera(user); + hedera_account[0]->updateBalanceFromHedera(user, this); } } } @@ -227,7 +225,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 150 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -244,38 +242,38 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 173 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -283,7 +281,10 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t

    Einen neuen Account anlegen

    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; - responseStream << "\t\t
    \n"; + responseStream << "\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; @@ -295,21 +296,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
    \n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 3fabc25c5..79d68a62e 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -1,6 +1,7 @@ #include "CryptoKey.h" #include "../SingletonManager/ErrorManager.h" +#include "../lib/DataTypeConverter.h" namespace controller { @@ -72,6 +73,9 @@ namespace controller { return nullptr; } MemoryBin* clearPassword = nullptr; + auto encrypted_private_key = model->getPrivateKeyEncrypted(); + auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key); + printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data()); if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { printf("[CryptoKey::getKeyPair] return null, error decrypting\n"); return nullptr; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 564752f72..6172db46c 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user) + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -101,7 +101,15 @@ namespace controller { query->sign(std::move(hedera_key_pair)); HederaRequest request; - request.request(query); + try { + request.request(query); + } + catch (Poco::Exception& ex) { + printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); + } + if (errorReceiver) { + errorReceiver->getErrors(&request); + } return false; } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 1a3fd9ace..7f08adddc 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -27,7 +27,7 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user); + bool updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/NodeServer.cpp b/src/cpp/controller/NodeServer.cpp index 6096b2839..625e61dad 100644 --- a/src/cpp/controller/NodeServer.cpp +++ b/src/cpp/controller/NodeServer.cpp @@ -1,9 +1,21 @@ #include "NodeServer.h" #include "../SingletonManager/ErrorManager.h" #include "../SingletonManager/ConnectionManager.h" +#include "Poco/RegularExpression.h" namespace controller { + Poco::RegularExpression g_filterHttp("^https?://"); + + std::string NodeServerConnection::getUriWithPort() const + { + std::string protocol; + g_filterHttp.extract(url, protocol); + return url.substr(protocol.size()) + ":" + std::to_string(port); + } + + + NodeServer::NodeServer(model::table::NodeServer* dbModel) { @@ -74,12 +86,13 @@ namespace controller { if (model::table::NodeServerIsHederaNode(type)) { select << ", node_hedera_id"; } - select << " from node_servers ORDER BY RAND() LIMIT 1" + select << " from node_servers where server_type = ? ORDER BY RAND() LIMIT 1" , Poco::Data::Keywords::into(result.url) , Poco::Data::Keywords::into(result.port); if (model::table::NodeServerIsHederaNode(type)) { select, Poco::Data::Keywords::into(hedera_node_id); } + select , Poco::Data::Keywords::bind((int)type); try { if (1 == select.execute()) { if (model::table::NodeServerIsHederaNode(type)) { diff --git a/src/cpp/controller/NodeServer.h b/src/cpp/controller/NodeServer.h index 8cc4b4e23..6945ac949 100644 --- a/src/cpp/controller/NodeServer.h +++ b/src/cpp/controller/NodeServer.h @@ -15,7 +15,11 @@ namespace controller { NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {} NodeServerConnection() :port(0) {}; - std::string getUrlWithPort() const { return url + ":" + std::to_string(port); } + // with http:// or https:// + inline std::string getUrlWithPort() const { return url + ":" + std::to_string(port); } + + // without http:// or https:// + std::string getUriWithPort() const; bool isValid() { return url != "" && port; } std::string url; diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index 46a767d97..0dad46954 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -31,6 +31,7 @@ namespace DataTypeConverter { std::string binToHex(const unsigned char* data, size_t size); std::string binToHex(const Poco::Nullable& nullableBin); inline std::string binToHex(const MemoryBin* data) { return binToHex(data->data(), data->size());} + inline std::string binToHex(const std::vector& data) { return binToHex(data.data(), data.size()); } //! \param pubkey pointer to array with crypto_sign_PUBLICKEYBYTES size std::string pubkeyToHex(const unsigned char* pubkey); diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index 8dff35024..ad9af855a 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -24,7 +24,7 @@ namespace model { bool sign(std::unique_ptr keyPairHedera); inline const proto::Query* getProtoQuery() const { return &mQueryProto; } - inline std::string getConnectionString() const { return mConnection.getUrlWithPort(); } + inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } protected: Query(const controller::NodeServerConnection& connection); From 761155fa8f9db7b5f02413bb9b5b93064c288e72 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:36:50 +0200 Subject: [PATCH 068/195] add some missing files --- skeema/gradido_login/node_servers.sql | 10 + src/cpp/HTTPInterface/AdminTopicPage.cpp | 128 +++++++++++ src/cpp/HTTPInterface/AdminTopicPage.h | 20 ++ .../HTTPInterface/PassphrasedTransaction.cpsp | 162 ++++++++++++++ src/cpp/controller/HederaRequest.cpp | 39 ++++ src/cpp/controller/HederaRequest.h | 39 ++++ src/cpsp/adminHederaAccount.cpsp | 203 ++++++++++++++++++ 7 files changed, 601 insertions(+) create mode 100644 skeema/gradido_login/node_servers.sql create mode 100644 src/cpp/HTTPInterface/AdminTopicPage.cpp create mode 100644 src/cpp/HTTPInterface/AdminTopicPage.h create mode 100644 src/cpp/HTTPInterface/PassphrasedTransaction.cpsp create mode 100644 src/cpp/controller/HederaRequest.cpp create mode 100644 src/cpp/controller/HederaRequest.h create mode 100644 src/cpsp/adminHederaAccount.cpsp diff --git a/skeema/gradido_login/node_servers.sql b/skeema/gradido_login/node_servers.sql new file mode 100644 index 000000000..88e4d8ac3 --- /dev/null +++ b/skeema/gradido_login/node_servers.sql @@ -0,0 +1,10 @@ +CREATE TABLE `node_servers` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `url` VARCHAR(255) NOT NULL, + `port` INT UNSIGNED NOT NULL, + `group_id` INT UNSIGNED NULL DEFAULT '0', + `server_type` INT UNSIGNED NOT NULL DEFAULT '0', + `node_hedera_id` INT UNSIGNED NULL DEFAULT '0', + `last_live_sign` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00', + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/HTTPInterface/AdminTopicPage.cpp b/src/cpp/HTTPInterface/AdminTopicPage.cpp new file mode 100644 index 000000000..d8926093e --- /dev/null +++ b/src/cpp/HTTPInterface/AdminTopicPage.cpp @@ -0,0 +1,128 @@ +#include "AdminTopicPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +AdminTopicPage::AdminTopicPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + + const char* pageName = "Topic"; + + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t
    "; + // end include header_large.cpsp + responseStream << "\n"; +#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t

    Topic Admin Page

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\t\n"; + responseStream << "
    \n"; + // begin include footer.cpsp + responseStream << "
    \n"; + responseStream << "

    Copyright © Gradido 2020

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "

    Login Server in Entwicklung

    \n"; + responseStream << "

    Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminTopicPage.h b/src/cpp/HTTPInterface/AdminTopicPage.h new file mode 100644 index 000000000..b02e5856c --- /dev/null +++ b/src/cpp/HTTPInterface/AdminTopicPage.h @@ -0,0 +1,20 @@ +#ifndef AdminTopicPage_INCLUDED +#define AdminTopicPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminTopicPage: public SessionHTTPRequestHandler +{ +public: + AdminTopicPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminTopicPage_INCLUDED diff --git a/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp b/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp new file mode 100644 index 000000000..debc1f296 --- /dev/null +++ b/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp @@ -0,0 +1,162 @@ +<%@ page class="PassphrasedTransaction" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="PageRequestMessagedHandler" %> +<%@ header include="PageRequestMessagedHandler.h" %> +<%! +#include "../SingletonManager/MemoryManager.h" +#include "../SingletonManager/SessionManager.h" +#include "../Crypto/KeyPair.h" +#include "../ServerConfig.h" + +#include "Poco/JSON/Object.h" +#include "Poco/JSON/Parser.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" + +enum PageState { + PAGE_STATE_INPUT, + PAGE_STATE_SUCCESS +}; +%> +<%% + std::string pageName = "Gradidos mit Passphrase überweisen"; + PageState state = PAGE_STATE_INPUT; + Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + std::string errorString =""; + + if(!form.empty()) { + auto passphrase = form.get("passphrase", ""); + bool passphraseValid = User::validatePassphrase(passphrase, &wordSource); + bool keysGenerated = false; + KeyPair keys; + if(!passphraseValid) + { + addError(new Error("Passphrase", "Fehler beim validieren der Passphrase")); + } + else + { + keysGenerated = keys.generateFromPassphrase(passphrase.data(), wordSource); + if(!keysGenerated) + { + addError(new Error("Passphrase", "Konnte keine Keys aus der Passphrase generieren")); + } + } + if(passphraseValid && keysGenerated) + { + // create session only for transaction + int session_id = 0; + auto session = sm->getNewSession(&session_id); + // create payload + Poco::JSON::Object requestJson; + Poco::JSON::Object pubkeys; + pubkeys.set("sender", keys.getPubkeyHex()); + pubkeys.set("receiver", form.get("recevier", "")); + requestJson.set("method", "moveTransaction"); + requestJson.set("pubkeys", pubkeys); + requestJson.set("memo", form.get("memo", "")); + requestJson.set("session_id", session_id); + + printf("[PassphrasedTransaction] prepare request\n"); + + // send to php server + Poco::Net::HTTPSClientSession httpsClientSession(ServerConfig::g_php_serverHost, 443); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); + + request.setChunkedTransferEncoding(true); + std::ostream& requestStream = httpsClientSession.sendRequest(request); + requestJson.stringify(requestStream); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = httpsClientSession.receiveResponse(response); + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + + printf("[PassphrasedTransaction] parse request result\n"); + try { + parsedJson = jsonParser.parse(responseStringStream); + + Poco::JSON::Object object = *parsedJson.extract(); + auto jsonState = object.get("state"); + std::string stateString = jsonState.convert(); + if (stateString == "error") { + addError(new Error("Transfer", "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError("php server", "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError("php server", "details:", object.get("details").convert().data())); + } + } else if(stateString == "success") { + printf("[PassphrasedTransaction] request success, wait on transaction ready\n"); + auto currentActiveTransaction = session->getNextReadyTransaction(); + while(currentActiveTransaction.isNull()) { + Poco::Thread::sleep(10); + currentActiveTransaction = session->getNextReadyTransaction(); + } + if(!currentActiveTransaction->isTransfer()) { + addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); + } else { + //auto signing = new SigningTransaction(currentActiveTransaction, user); + printf("[PassphrasedTransaction] cannot sign, implementation missing\n"); + /*if(!signing->run()) { + + } else { + addError(new Error("Transaction", "Fehler beim signieren, bitter erneut versuchen")); + }*/ + // remove transaction from list + //mSession->finalizeTransaction(true, true); + } + } + } + catch (Poco::Exception& ex) { + //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); + addError(new ParamError("Transfer", "Fehler beim erstellen der Transaktion, bitte erneut versuchen", ex.displayText().data())); + errorString = responseStringStream.str(); + sm->releaseSession(session); + session = nullptr; + } + if(session) { + sm->releaseSession(session); + } + } + } + + +%><%@ include file="header_old.cpsp" %> +<% if("" == errorString) { %> + <%= errorString %> +<% } %> +
    + <%= getErrorsHtml() %> + <% if(PAGE_STATE_INPUT == state) { %> + +
    +
    +

    +

    +

    +

    +

    + + "/> +

    +

    +
    +
    + <% } else if(PAGE_STATE_SUCCESS == state) { %> +

    Gradidos wurden erfolgreich überwiesen.

    + Weitere Gradidos überweisen + <% } %> +
    +<%@ include file="footer.cpsp" %> diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp new file mode 100644 index 000000000..ec1c6c2a0 --- /dev/null +++ b/src/cpp/controller/HederaRequest.cpp @@ -0,0 +1,39 @@ +#include "HederaRequest.h" +#include "../proto/hedera/CryptoService.grpc.pb.h" + +#include +#include +#include +#include +#include + +HederaRequest::HederaRequest() +{ + +} + +HederaRequest::~HederaRequest() +{ + +} + +HederaRequestReturn HederaRequest::request(model::hedera::Query* query) +{ + auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); + grpc::ClientContext context; + std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + + std::chrono::milliseconds(100); + context.set_deadline(deadline); + + auto proto_query = query->getProtoQuery(); + proto::Response* response = nullptr; + if (proto_query->has_cryptogetaccountbalance()) { + auto stub = proto::CryptoService::NewStub(channel); + auto connect_string = query->getConnectionString(); + printf("try connection to hedera with: %s\n", connect_string.data()); + auto status = stub->cryptoGetBalance(&context, *proto_query, response); + addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); + printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); + } + return HEDERA_REQUEST_RETURN_OK; +} \ No newline at end of file diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h new file mode 100644 index 000000000..692215f8d --- /dev/null +++ b/src/cpp/controller/HederaRequest.h @@ -0,0 +1,39 @@ +#ifndef __GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_ +#define __GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_ +/*! +* +* \author: Dario Rekowski +* +* \date: 31.08.2020 +* +* \brief: Class for Hedera Requests +* +*/ + +#include "../controller/NodeServer.h" +#include "../model/hedera/Query.h" + +enum HederaRequestReturn +{ + HEDERA_REQUEST_RETURN_OK, + HEDERA_REQUEST_RETURN_PARSE_ERROR, + HEDERA_REQUEST_RETURN_ERROR, + HEDERA_REQUEST_CONNECT_ERROR +}; + +// NodeServerConnection +class HederaRequest : public ErrorList +{ +public: + HederaRequest(); + ~HederaRequest(); + + HederaRequestReturn request(model::hedera::Query* query); + +protected: + +}; + + +#endif //__GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_ +// \ No newline at end of file diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp new file mode 100644 index 000000000..b4fd1f485 --- /dev/null +++ b/src/cpsp/adminHederaAccount.cpsp @@ -0,0 +1,203 @@ +<%@ page class="AdminHederaAccountPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! + +#include "../controller/HederaAccount.h" +#include "../controller/HederaId.h" +#include "../controller/CryptoKey.h" +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" + +#include "../ServerConfig.h" + +#include "Poco/URI.h" + +%> +<%% + const char* pageName = "Hedera Account"; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + auto user = mSession->getNewUser(); + + Poco::URI uri(request.getURI()); + auto uri_query = uri.getQueryParameters(); + std::string action = ""; + std::string account_id_from_query; + if(uri_query.size() >= 2) { + if(uri_query[0].first == "action") { + action = uri_query[0].second; + } + if(uri_query[1].first == "account_id") { + account_id_from_query = uri_query[1].second; + } + } + if(action == "updateBalance") { + int account_id = 0; + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); + } else { + auto hedera_account = controller::HederaAccount::load("id", account_id); + if(!hedera_account.size() || hedera_account[0].isNull()) { + addError(new Error("Action Update Balance", "hedera id not found")); + } else { + hedera_account[0]->updateBalanceFromHedera(user, this); + } + } + } + // add + else if(!form.empty()) { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); + } + if(0 == errorCount()) { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); + } + + } + + // list accounts + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
    +
    +
    +

    Deine Hedera Accounts

    +
    +
    +
    +
    Hedera Id
    +
    Balance
    +
    Server Type
    +
    Last Updated
    +
    Aktionen
    +
    + <% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { + auto hedera_account_model = (*it)->getModel(); + auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + %> +
    +
    <%= (*it)->getHederaId()->getModel()->toString() %>
    +
    <%= hedera_account_model->getBalanceDouble() %> hbar
    +
    <%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
    +
    <%= hedera_account_model->getUpdatedString() %>
    +
    + +
    + <% } %> +
    +
    +
    +

    Einen neuen Account anlegen

    +
    +
    +
    + + + + + + + + + + + "> +
    +
    +<%@ include file="footer.cpsp" %> From 65756fc784db63009deff9d9b2c0bd8a9a92ca8e Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:40:19 +0200 Subject: [PATCH 069/195] missing class name --- src/cpp/model/table/ModelBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 2ec7a3ee2..9a1e823fe 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -151,7 +151,7 @@ namespace model { } template - std::vector loadAllFromDB() + std::vector ModelBase::loadAllFromDB() { std::vector results; Poco::ScopedLock _lock(mWorkMutex); From 82605d89df0be5fed4712d9cde819ff639dc3d7b Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 1 Sep 2020 11:47:19 +0200 Subject: [PATCH 070/195] fix error only occuring in linux --- src/cpp/controller/Group.cpp | 3 ++- src/cpp/controller/HederaAccount.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cpp/controller/Group.cpp b/src/cpp/controller/Group.cpp index 2d809da07..f835e6986 100644 --- a/src/cpp/controller/Group.cpp +++ b/src/cpp/controller/Group.cpp @@ -42,7 +42,8 @@ namespace controller { // work around for not working call to loadAllFromDB auto cm = ConnectionManager::getInstance(); - Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); select << "SELECT id, alias, name, url, description FROM " << db->getTableName() , Poco::Data::Keywords::into(group_list); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 6172db46c..58c71b5ec 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -46,10 +46,11 @@ namespace controller { auto db = new model::table::HederaAccount(); std::vector group_list; // throw an unresolved external symbol error - //group_list = db->loadAllFromDB(); + group_list = db->loadAllFromDB(); // work around for not working call to loadAllFromDB - auto cm = ConnectionManager::getInstance(); + /*auto cm = ConnectionManager::getInstance(); + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); select << "SELECT id, alias, name, url, description FROM " << db->getTableName() @@ -62,7 +63,7 @@ namespace controller { catch (Poco::Exception& ex) { printf("[Group::listAll] poco exception: %s\n", ex.displayText().data()); } - // work around end + //*/ //work around end std::vector> resultVector; resultVector.reserve(group_list.size()); From 2130cea2862908bb7a5e7c4040992e0f434fbc94 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 2 Sep 2020 14:06:23 +0200 Subject: [PATCH 071/195] use protobuf from inside grpc, even for parsing protofiles for easy version switch, fix html error --- CMakeLists.txt | 15 ++++++++++++++- README | 1 + conanfile.txt | 1 - compile_proto.sh => parse_proto.sh | 0 .../HTTPInterface/AdminHederaAccountPage.cpp | 17 ++++++++--------- src/cpp/controller/HederaAccount.cpp | 1 - src/cpp/controller/HederaRequest.cpp | 10 +++++++++- src/cpp/model/hedera/Query.cpp | 4 ++-- src/cpsp/adminHederaAccount.cpsp | 1 - windows_parse_proto.sh | 19 +++++++++++++++++++ 10 files changed, 53 insertions(+), 16 deletions(-) rename compile_proto.sh => parse_proto.sh (100%) mode change 100755 => 100644 create mode 100644 windows_parse_proto.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index d679dfd63..be4388e9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ project(Gradido_LoginServer C CXX) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin" ) SET ( CMAKE_CXX_FLAGS "-std=c++17" ) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories( "dependencies" @@ -12,6 +14,7 @@ include_directories( "dependencies/mariadb-connector-c/build/include" "dependencies/spirit-po/include" "dependencies/grpc/include" + "dependencies/grpc/third_party/protobuf/src" "src/cpp/proto" #"dependencies/mariadb-connector-c/build/include" #"dependencies/mariadb-connector-c/include" @@ -99,6 +102,7 @@ set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/D set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") set(GRPC_RE2_PATH "dependencies/grpc/_build/third_party/re2/Debug") +set(GRPC_PROTOBUF_DEBUG_PATH "dependencies/grpc/_build/third_party/protobuf/Debug") find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) @@ -112,6 +116,9 @@ find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_RE2 re2 ${GRPC_RE2_PATH} REQUIRED) +find_library(PROTOBUF_LIB_DEBUG libprotobufd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) +find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) +find_library(PROTOBUF_LIBC_DEBUG libprotocd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) set(GRPC_LIBS @@ -123,6 +130,12 @@ set(GRPC_LIBS ${GRPC_BORING_SSL_SSL} ${GRPC_RE2} ) +set(PROTOBUF_DEBUG_LIBS + ${PROTOBUF_LIB_DEBUG} + ${PROTOBUF_LIB_LITE_DEBUG} + ${PROTOBUF_LIBC_DEBUG} +) + set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") @@ -174,7 +187,7 @@ target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::f if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS}) +TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) target_link_libraries(Gradido_LoginServer libmariadb protoc protobuf -pthread) endif(WIN32) diff --git a/README b/README index 89783a878..993dd4afa 100644 --- a/README +++ b/README @@ -25,6 +25,7 @@ mkdir _build cd _build cmake .. make +# under windows build at least release for protoc.exe and grpc c++ plugin cd ../../../ # get more dependencies with conan (need conan from https://conan.io/) diff --git a/conanfile.txt b/conanfile.txt index 96bd6f5c8..a6c09d9fa 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,7 +1,6 @@ [requires] Poco/1.9.4@pocoproject/stable libsodium/1.0.18@bincrafters/stable -protobuf/3.9.1@bincrafters/stable boost/1.71.0@conan/stable gtest/1.8.1@bincrafters/stable diff --git a/compile_proto.sh b/parse_proto.sh old mode 100755 new mode 100644 similarity index 100% rename from compile_proto.sh rename to parse_proto.sh diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index a9d4165c3..e98a02d92 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -264,16 +264,15 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request #line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -282,7 +281,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -296,21 +295,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
    \n"; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 58c71b5ec..57cb14672 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -28,7 +28,6 @@ namespace controller { { auto db = new model::table::HederaAccount(); auto hedera_account_list = db->loadFromDB(fieldName, fieldValue, 2); - std::vector> resultVector; resultVector.reserve(hedera_account_list.size()); for (auto it = hedera_account_list.begin(); it != hedera_account_list.end(); it++) { diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index ec1c6c2a0..32c6772c6 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -1,6 +1,8 @@ #include "HederaRequest.h" #include "../proto/hedera/CryptoService.grpc.pb.h" +#include "../lib/DataTypeConverter.h" + #include #include #include @@ -22,16 +24,22 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query) auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); grpc::ClientContext context; std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + - std::chrono::milliseconds(100); + std::chrono::milliseconds(10000); context.set_deadline(deadline); + grpc::CompletionQueue cq; auto proto_query = query->getProtoQuery(); + auto proto_query_serialized = proto_query->SerializeAsString(); + auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); + printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); proto::Response* response = nullptr; if (proto_query->has_cryptogetaccountbalance()) { auto stub = proto::CryptoService::NewStub(channel); auto connect_string = query->getConnectionString(); printf("try connection to hedera with: %s\n", connect_string.data()); + //auto stream = stub->PrepareAsynccryptoGetBalance(&context, *proto_query, &cq); auto status = stub->cryptoGetBalance(&context, *proto_query, response); + //stream->StartCall(); addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); } diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index d47449bc6..39b3700c4 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -25,7 +25,7 @@ namespace model { auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance(); accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); - query_header->set_responsetype(proto::ANSWER_ONLY); + query_header->set_responsetype(proto::COST_ANSWER); auto transaction = query_header->mutable_payment(); //auto transaction_body = transaction->mutable_body(); // body content @@ -48,7 +48,7 @@ namespace model { auto account_amounts = transfer_list->mutable_accountamounts(); account_amounts->Add(); auto account_amount = account_amounts->Mutable(0); - account_amount->set_amount(0); + account_amount->set_amount(1000); connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); return query; diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index b4fd1f485..5379e4ef4 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -170,7 +170,6 @@
    <%= hedera_account_model->getBalanceDouble() %> hbar
    <%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
    <%= hedera_account_model->getUpdatedString() %>
    -
    diff --git a/windows_parse_proto.sh b/windows_parse_proto.sh new file mode 100644 index 000000000..4c5d56d47 --- /dev/null +++ b/windows_parse_proto.sh @@ -0,0 +1,19 @@ +#!/bin/bash +if [ ! -d "./src/cpp/proto" ] ; then + mkdir ./src/cpp/proto +fi +if [ ! -d "./src/cpp/proto/gradido" ] ; then + mkdir ./src/cpp/proto/gradido +fi +PROTOC_PATH=./dependencies/grpc/_build/third_party/protobuf/Release +CPP_PLUGIN_PATH=./dependencies/grpc/_build/Release +$PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto + +if [ ! -d "./src/cpp/proto/hedera" ] ; then + mkdir ./src/cpp/proto/hedera +fi + +GOOGLE_PROTOBUF_INCLUDES=./dependencies/grpc/third_party/protobuf/src +$PROTOC_PATH/protoc --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto + + From 73d10f7773ff524179ba37698e78e03c03749112 Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 3 Sep 2020 12:43:32 +0200 Subject: [PATCH 072/195] hedera query get balance now working =D --- .../HTTPInterface/AdminHederaAccountPage.cpp | 36 +- src/cpp/HTTPInterface/ElopageWebhook.h | 4 +- .../PageRequestMessagedHandler.h | 4 +- src/cpp/JSONInterface/JsonRequestHandler.cpp | 279 +++++---- src/cpp/JSONInterface/JsonRequestHandler.h | 4 +- src/cpp/SingletonManager/ConnectionManager.h | 4 +- src/cpp/SingletonManager/ErrorManager.cpp | 14 +- src/cpp/SingletonManager/ErrorManager.h | 10 +- src/cpp/SingletonManager/SessionManager.cpp | 6 +- src/cpp/SingletonManager/SessionManager.h | 2 +- src/cpp/controller/HederaAccount.cpp | 24 +- src/cpp/controller/HederaAccount.h | 2 +- src/cpp/controller/HederaRequest.cpp | 62 +- src/cpp/controller/HederaRequest.h | 8 +- src/cpp/lib/DataTypeConverter.cpp | 9 +- src/cpp/lib/DataTypeConverter.h | 5 +- src/cpp/lib/Error.cpp | 10 +- src/cpp/lib/Error.h | 128 ++-- src/cpp/lib/JsonRequest.cpp | 91 ++- src/cpp/lib/JsonRequest.h | 6 +- src/cpp/lib/MultithreadContainer.cpp | 4 +- src/cpp/lib/Notification.cpp | 7 + src/cpp/lib/Notification.h | 24 + .../{ErrorList.cpp => NotificationList.cpp} | 414 ++++++------- .../lib/{ErrorList.h => NotificationList.h} | 150 +++-- src/cpp/lib/Success.cpp | 52 ++ src/cpp/lib/Success.h | 30 + src/cpp/model/Session.h | 563 +++++++++--------- src/cpp/model/TransactionBase.h | 4 +- src/cpp/model/User.cpp | 4 +- src/cpp/model/User.h | 8 +- src/cpp/model/email/Email.h | 4 +- .../hedera/CryptoTransferTransaction.cpp | 53 ++ .../model/hedera/CryptoTransferTransaction.h | 40 ++ src/cpp/model/hedera/Query.cpp | 80 ++- src/cpp/model/hedera/Query.h | 6 +- src/cpp/model/hedera/Response.cpp | 32 + src/cpp/model/hedera/Response.h | 38 ++ src/cpp/model/hedera/Transaction.cpp | 43 ++ src/cpp/model/hedera/Transaction.h | 38 ++ src/cpp/model/hedera/TransactionBody.cpp | 47 ++ src/cpp/model/hedera/TransactionBody.h | 39 ++ src/cpp/model/table/ModelBase.h | 2 +- src/cpp/tasks/ProcessingTransaction.h | 4 +- src/cpp/tasks/SigningTransaction.h | 89 ++- src/cpp/tasks/Task.cpp | 4 +- src/cpsp/adminHederaAccount.cpsp | 7 + 47 files changed, 1553 insertions(+), 941 deletions(-) create mode 100644 src/cpp/lib/Notification.cpp create mode 100644 src/cpp/lib/Notification.h rename src/cpp/lib/{ErrorList.cpp => NotificationList.cpp} (74%) rename src/cpp/lib/{ErrorList.h => NotificationList.h} (74%) create mode 100644 src/cpp/lib/Success.cpp create mode 100644 src/cpp/lib/Success.h create mode 100644 src/cpp/model/hedera/CryptoTransferTransaction.cpp create mode 100644 src/cpp/model/hedera/CryptoTransferTransaction.h diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index e98a02d92..fa99a7b35 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -12,6 +12,8 @@ #include "../controller/HederaId.h" #include "../controller/CryptoKey.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/Success.h" #include "../SingletonManager/SessionManager.h" #include "../ServerConfig.h" @@ -37,12 +39,14 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 20 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 22 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Profiler hedera_time; + std::string hedera_time_string; Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); @@ -65,7 +69,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { + hedera_time.reset(); hedera_account[0]->updateBalanceFromHedera(user, this); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } } @@ -225,7 +231,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 150 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -242,37 +248,37 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -281,7 +287,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -295,21 +301,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
    \n"; diff --git a/src/cpp/HTTPInterface/ElopageWebhook.h b/src/cpp/HTTPInterface/ElopageWebhook.h index bf8ea4efc..77c60b155 100644 --- a/src/cpp/HTTPInterface/ElopageWebhook.h +++ b/src/cpp/HTTPInterface/ElopageWebhook.h @@ -4,7 +4,7 @@ #include "PageRequestMessagedHandler.h" #include "../tasks/CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "Poco/Net/NameValueCollection.h" @@ -14,7 +14,7 @@ public: void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); }; -class HandleElopageRequestTask : public UniLib::controller::CPUTask, protected ErrorList +class HandleElopageRequestTask : public UniLib::controller::CPUTask, protected NotificationList { public: HandleElopageRequestTask(Poco::Net::NameValueCollection& requestData); diff --git a/src/cpp/HTTPInterface/PageRequestMessagedHandler.h b/src/cpp/HTTPInterface/PageRequestMessagedHandler.h index 2e47b398d..396fc8a4e 100644 --- a/src/cpp/HTTPInterface/PageRequestMessagedHandler.h +++ b/src/cpp/HTTPInterface/PageRequestMessagedHandler.h @@ -2,7 +2,7 @@ #define PAGE_REQUEST_MESSAGE_HANDLER_INCLUDED #include "../model/Session.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/Profiler.h" #include "../SingletonManager/LanguageManager.h" @@ -11,7 +11,7 @@ #include "Poco/Net/HTMLForm.h" #include "Poco/RegularExpression.h" -class PageRequestMessagedHandler : public Poco::Net::HTTPRequestHandler, public ErrorList +class PageRequestMessagedHandler : public Poco::Net::HTTPRequestHandler, public NotificationList { public: PageRequestMessagedHandler() {} diff --git a/src/cpp/JSONInterface/JsonRequestHandler.cpp b/src/cpp/JSONInterface/JsonRequestHandler.cpp index b66cba495..1601c764c 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandler.cpp @@ -1,141 +1,138 @@ -#include "JsonRequestHandler.h" - -#include "Poco/Net/HTTPServerRequest.h" -#include "Poco/Net/HTTPServerResponse.h" - -#include "Poco/URI.h" -#include "Poco/DeflatingStream.h" - -#include "Poco/JSON/Parser.h" - -#include "../ServerConfig.h" - -#include "../lib/DataTypeConverter.h" -#include "../SingletonManager/SessionManager.h" - - -void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) -{ - - response.setChunkedTransferEncoding(false); - response.setContentType("application/json"); - if (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_CORS_ALL) { - response.set("Access-Control-Allow-Origin", "*"); - response.set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); - } - //bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); - //if (_compressResponse) response.set("Content-Encoding", "gzip"); - - std::ostream& responseStream = response.send(); - //Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); - //std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; - - auto method = request.getMethod(); - std::istream& request_stream = request.stream(); - Poco::JSON::Object* json_result = nullptr; - if (method == "POST" || method == "PUT") { - // extract parameter from request - Poco::Dynamic::Var parsedResult = parseJsonWithErrorPrintFile(request_stream); - - if (parsedResult.size() != 0) { - json_result = handle(parsedResult); - } - else { - json_result = stateError("empty body"); - } - - } - else if(method == "GET") { - Poco::URI uri(request.getURI()); - auto queryParameters = uri.getQueryParameters(); - json_result = handle(queryParameters); - } - - if (json_result) { - if (!json_result->isNull("session_id")) { - int session_id = 0; - try { - json_result->get("session_id").convert(session_id); - } - catch (Poco::Exception& e) { - ErrorList erros; - erros.addError(new Error("json request", "invalid session_id")); - erros.sendErrorsAsEmail(); - } - if (session_id) { - auto session = SessionManager::getInstance()->getSession(session_id); - response.addCookie(session->getLoginCookie()); - } - } - json_result->stringify(responseStream); - delete json_result; - } - - //if (_compressResponse) _gzipStream.close(); -} - - -Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& request_stream, ErrorList* errorHandler /* = nullptr*/, const char* functionName /* = nullptr*/) -{ - // debugging answer - - std::stringstream responseStringStream; - for (std::string line; std::getline(request_stream, line); ) { - responseStringStream << line << std::endl; - } - - // extract parameter from request - Poco::JSON::Parser jsonParser; - Poco::Dynamic::Var parsedJson; - try { - parsedJson = jsonParser.parse(responseStringStream.str()); - - return parsedJson; - } - catch (Poco::Exception& ex) { - if (errorHandler) { - errorHandler->addError(new ParamError(functionName, "error parsing request answer", ex.displayText().data())); - errorHandler->sendErrorsAsEmail(responseStringStream.str()); - } - std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d_%m_%yT%H_%M_%S"); - std::string filename = dateTimeString + "_response.html"; - FILE* f = fopen(filename.data(), "wt"); - if (f) { - std::string responseString = responseStringStream.str(); - fwrite(responseString.data(), 1, responseString.size(), f); - fclose(f); - } - return Poco::Dynamic::Var(); - } - return Poco::Dynamic::Var(); -} - -Poco::JSON::Object* JsonRequestHandler::stateError(const char* msg, std::string details) -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", "error"); - result->set("msg", msg); - if (details != "") { - result->set("details", details); - } - return result; -} - -Poco::JSON::Object* JsonRequestHandler::stateSuccess() -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", "success"); - return result; -} - -Poco::JSON::Object* JsonRequestHandler::customStateError(const char* state, const char* msg, std::string details/* = ""*/) -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", state); - result->set("msg", msg); - if (details != "") { - result->set("details", details); - } - return result; -} - +#include "JsonRequestHandler.h" + +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" + +#include "Poco/URI.h" +#include "Poco/DeflatingStream.h" + +#include "Poco/JSON/Parser.h" + +#include "../ServerConfig.h" + +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" + +void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + + response.setChunkedTransferEncoding(false); + response.setContentType("application/json"); + if (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_CORS_ALL) { + response.set("Access-Control-Allow-Origin", "*"); + response.set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); + } + //bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + //if (_compressResponse) response.set("Content-Encoding", "gzip"); + + std::ostream& responseStream = response.send(); + //Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + //std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + + auto method = request.getMethod(); + std::istream& request_stream = request.stream(); + Poco::JSON::Object* json_result = nullptr; + if (method == "POST" || method == "PUT") { + // extract parameter from request + Poco::Dynamic::Var parsedResult = parseJsonWithErrorPrintFile(request_stream); + + if (parsedResult.size() != 0) { + json_result = handle(parsedResult); + } + else { + json_result = stateError("empty body"); + } + } + else if(method == "GET") { + Poco::URI uri(request.getURI()); + auto queryParameters = uri.getQueryParameters(); + json_result = handle(queryParameters); + } + + if (json_result) { + if (!json_result->isNull("session_id")) { + int session_id = 0; + try { + json_result->get("session_id").convert(session_id); + } + catch (Poco::Exception& e) { + ErrorList erros; + erros.addError(new Error("json request", "invalid session_id")); + erros.sendErrorsAsEmail(); + } + if (session_id) { + auto session = SessionManager::getInstance()->getSession("session_id"); + response.addCookie(session->getLoginCookie()); + } + } + json_result->stringify(responseStream); + delete json_result; + } + + //if (_compressResponse) _gzipStream.close(); +} + + +Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& request_stream, NotificationList* errorHandler /* = nullptr*/, const char* functionName /* = nullptr*/) +{ + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + + return parsedJson; + } + catch (Poco::Exception& ex) { + if (errorHandler) { + errorHandler->addError(new ParamError(functionName, "error parsing request answer", ex.displayText().data())); + errorHandler->sendErrorsAsEmail(responseStringStream.str()); + } + std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d_%m_%yT%H_%M_%S"); + std::string filename = dateTimeString + "_response.html"; + FILE* f = fopen(filename.data(), "wt"); + if (f) { + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + } + return Poco::Dynamic::Var(); + } + return Poco::Dynamic::Var(); +} + +Poco::JSON::Object* JsonRequestHandler::stateError(const char* msg, std::string details) +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "error"); + result->set("msg", msg); + if (details != "") { + result->set("details", details); + } + return result; +} + +Poco::JSON::Object* JsonRequestHandler::stateSuccess() +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "success"); + return result; +} + +Poco::JSON::Object* JsonRequestHandler::customStateError(const char* state, const char* msg, std::string details/* = ""*/) +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", state); + result->set("msg", msg); + if (details != "") { + result->set("details", details); + } + return result; +} diff --git a/src/cpp/JSONInterface/JsonRequestHandler.h b/src/cpp/JSONInterface/JsonRequestHandler.h index 72230bfe4..90c3e3171 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.h +++ b/src/cpp/JSONInterface/JsonRequestHandler.h @@ -4,7 +4,7 @@ #include "Poco/Net/HTTPRequestHandler.h" #include "Poco/JSON/Object.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" class JsonRequestHandler : public Poco::Net::HTTPRequestHandler @@ -15,7 +15,7 @@ public: virtual Poco::JSON::Object* handle(Poco::Dynamic::Var params) = 0; - static Poco::Dynamic::Var parseJsonWithErrorPrintFile(std::istream& request_stream, ErrorList* errorHandler = nullptr, const char* functionName = nullptr); + static Poco::Dynamic::Var parseJsonWithErrorPrintFile(std::istream& request_stream, NotificationList* errorHandler = nullptr, const char* functionName = nullptr); protected: Poco::JSON::Object* mResultJson; diff --git a/src/cpp/SingletonManager/ConnectionManager.h b/src/cpp/SingletonManager/ConnectionManager.h index 72c8b02e4..2c0d4968a 100644 --- a/src/cpp/SingletonManager/ConnectionManager.h +++ b/src/cpp/SingletonManager/ConnectionManager.h @@ -9,7 +9,7 @@ #include "../MySQL/Poco/Connector.h" #include "Poco/Exception.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" enum ConnectionType { CONNECTION_MYSQL_LOGIN_SERVER, @@ -17,7 +17,7 @@ enum ConnectionType { CONNECTION_MAX }; -class ConnectionManager : public ErrorList +class ConnectionManager : public NotificationList { public: ~ConnectionManager(); diff --git a/src/cpp/SingletonManager/ErrorManager.cpp b/src/cpp/SingletonManager/ErrorManager.cpp index 090a6f9dd..b4df67974 100644 --- a/src/cpp/SingletonManager/ErrorManager.cpp +++ b/src/cpp/SingletonManager/ErrorManager.cpp @@ -4,7 +4,7 @@ #include "Poco/Net/SecureSMTPClientSession.h" #include "Poco/Net/StringPartSource.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../model/email/Email.h" @@ -34,19 +34,19 @@ ErrorManager::~ErrorManager() mErrorsMap.clear(); } -void ErrorManager::addError(Error* error, bool log/* = true*/) +void ErrorManager::addError(Notification* error, bool log/* = true*/) { DHASH id = DRMakeStringHash(error->getFunctionName()); mWorkingMutex.lock(); auto it = mErrorsMap.find(id); - std::list* list = nullptr; + std::list* list = nullptr; //printf("[ErrorManager::addError] error with function: %s, %s\n", error->getFunctionName(), error->getMessage()); if(log) mLogging.error("[ErrorManager::addError] %s", error->getString(false)); if (it == mErrorsMap.end()) { - list = new std::list; - mErrorsMap.insert(std::pair*>(id, list)); + list = new std::list; + mErrorsMap.insert(std::pair*>(id, list)); } else { list = it->second; @@ -62,9 +62,9 @@ void ErrorManager::addError(Error* error, bool log/* = true*/) } -int ErrorManager::getErrors(ErrorList* send) +int ErrorManager::getErrors(NotificationList* send) { - Error* error = nullptr; + Notification* error = nullptr; int iCount = 0; while (error = send->getLastError()) { addError(error, false); diff --git a/src/cpp/SingletonManager/ErrorManager.h b/src/cpp/SingletonManager/ErrorManager.h index e59bd7d35..a0e427d9e 100644 --- a/src/cpp/SingletonManager/ErrorManager.h +++ b/src/cpp/SingletonManager/ErrorManager.h @@ -15,7 +15,7 @@ #include #include #include -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/DRHash.h" #include "../tasks/CPUTask.h" @@ -24,7 +24,7 @@ #include "Poco/Net/MailMessage.h" -class ErrorManager : public IErrorCollection +class ErrorManager : public INotificationCollection { public: ~ErrorManager(); @@ -32,9 +32,9 @@ public: static ErrorManager* getInstance(); // will called delete on error - virtual void addError(Error* error, bool log = true); + virtual void addError(Notification* error, bool log = true); - int getErrors(ErrorList* send); + int getErrors(NotificationList* send); virtual void sendErrorsAsEmail(); @@ -43,7 +43,7 @@ protected: // access mutex Poco::Mutex mWorkingMutex; - std::map*> mErrorsMap; + std::map*> mErrorsMap; // how many errors should be stored // poco logging diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 1f7e87303..1eb9c436c 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -175,7 +175,7 @@ Session* SessionManager::getNewSession(int* handle) } } else { - ErrorList errors; + NotificationList errors; errors.addError(new Error(functionName, "found dead locked session, keeping in memory without reference")); errors.addError(new ParamError(functionName, "last succeeded lock:", result->getLastSucceededLock().data())); errors.sendErrorsAsEmail(); @@ -249,7 +249,7 @@ bool SessionManager::releaseSession(int requestHandleSession) session->setActive(false); } else { - ErrorList errors; + NotificationList errors; errors.addError(new Error("SessionManager::releaseSession", "found dead locked session")); errors.sendErrorsAsEmail(); mRequestSessionMap.erase(requestHandleSession); @@ -590,7 +590,7 @@ void SessionManager::deleteLoginCookies(Poco::Net::HTTPServerRequest& request, P //session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); } -bool SessionManager::checkPwdValidation(const std::string& pwd, ErrorList* errorReciver) +bool SessionManager::checkPwdValidation(const std::string& pwd, NotificationList* errorReciver) { if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) == ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) { return true; diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index e1469d539..9b83c712d 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -69,7 +69,7 @@ public: bool isValid(const std::string& subject, SessionValidationTypes validationType); //! \return true if password is valid - bool checkPwdValidation(const std::string& pwd, ErrorList* errorReciver); + bool checkPwdValidation(const std::string& pwd, NotificationList* errorReciver); void checkTimeoutSession(); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 57cb14672..6fabe2848 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver/* = nullptr*/) + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -86,27 +86,45 @@ namespace controller { auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); if (crypto_key.isNull()) { - printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); + if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));} + else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); } return false; } auto hedera_key_pair = crypto_key->getKeyPair(user); if (!hedera_key_pair) { + if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));} printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); return false; } + auto query = model::hedera::Query::getBalance(mHederaID, hedera_node); + if (!query) { printf("[%s] error creating query\n", functionName); } query->sign(std::move(hedera_key_pair)); HederaRequest request; + model::hedera::Response response; try { - request.request(query); + if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response) && proto::OK == response.getResponseCode()) { + account_model->updateIntoDB("balance", response.getAccountBalance()); + } + else { + if (errorReceiver) { + errorReceiver->addError(new Error("Hedera", "Hedera request failed")); + errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); + } + else { + printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data()); + } + } + //request.requestViaPHPRelay(query); } catch (Poco::Exception& ex) { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } + if (errorReceiver) { errorReceiver->getErrors(&request); } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 7f08adddc..d76420b78 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -27,7 +27,7 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver = nullptr); + bool updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 32c6772c6..308ffa5e8 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -9,6 +9,7 @@ #include #include + HederaRequest::HederaRequest() { @@ -19,29 +20,62 @@ HederaRequest::~HederaRequest() } -HederaRequestReturn HederaRequest::request(model::hedera::Query* query) +HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee/* = 0*/) { auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); + grpc::ClientContext context; std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + - std::chrono::milliseconds(10000); + std::chrono::milliseconds(5000); context.set_deadline(deadline); - grpc::CompletionQueue cq; + //grpc::CompletionQueue cq; auto proto_query = query->getProtoQuery(); + auto proto_query_serialized = proto_query->SerializeAsString(); - auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); - printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); - proto::Response* response = nullptr; + //auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); + //printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); + + auto proto_response = response->getResponsePtr(); + auto connect_string = query->getConnectionString(); + if (proto_query->has_cryptogetaccountbalance()) { - auto stub = proto::CryptoService::NewStub(channel); - auto connect_string = query->getConnectionString(); - printf("try connection to hedera with: %s\n", connect_string.data()); - //auto stream = stub->PrepareAsynccryptoGetBalance(&context, *proto_query, &cq); - auto status = stub->cryptoGetBalance(&context, *proto_query, response); - //stream->StartCall(); - addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); - printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); + auto stub = proto::CryptoService::NewStub(channel); + // crypto account get balance currently hasn't fees + query->setResponseType(proto::ANSWER_ONLY); + + auto status = stub->cryptoGetBalance(&context, *proto_query, proto_response); + if (status.ok()) { + return HEDERA_REQUEST_RETURN_OK; + } + else { + addError(new ParamError("Hedera Request", "crypto get balance error message:", status.error_message())); + addError(new ParamError("Hedera Request", "details: ", status.error_details())); + return HEDERA_REQUEST_RETURN_ERROR; + } + + } return HEDERA_REQUEST_RETURN_OK; +} + +#include "Poco/JSON/Object.h" +#include "../lib/JsonRequest.h" + +HederaRequestReturn HederaRequest::requestViaPHPRelay(model::hedera::Query* query) +{ + JsonRequest phpRelay("***REMOVED***", 88); + Poco::Net::NameValueCollection parameters; + std::string query_string = query->getProtoQuery()->SerializeAsString(); + //auto query_base64 = DataTypeConverter::binToBase64((const unsigned char*)query_string.data(), query_string.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); + //auto findPos = query_string.find_first_of("\u"); + auto query_hex = DataTypeConverter::binToHex((const unsigned char*)query_string.data(), query_string.size()); + parameters.set("content", query_hex.substr(0, query_hex.size()-1)); + parameters.set("server", query->getConnectionString()); + parameters.set("method", "getBalance"); + parameters.set("service", "crypto"); + phpRelay.requestGRPCRelay(parameters); + //phpRelay.request("") + + return HEDERA_REQUEST_RETURN_OK; } \ No newline at end of file diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 692215f8d..327ee7634 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -12,6 +12,8 @@ #include "../controller/NodeServer.h" #include "../model/hedera/Query.h" +#include "../model/hedera/Transaction.h" +#include "../model/hedera/Response.h" enum HederaRequestReturn { @@ -22,13 +24,15 @@ enum HederaRequestReturn }; // NodeServerConnection -class HederaRequest : public ErrorList +class HederaRequest : public NotificationList { public: HederaRequest(); ~HederaRequest(); - HederaRequestReturn request(model::hedera::Query* query); + HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); + //! for testing, didn't work server say invalid json :/ + HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); protected: diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index a97cb8d0e..72e6aceb8 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -138,18 +138,17 @@ namespace DataTypeConverter } - std::string binToBase64(const MemoryBin* data) + std::string binToBase64(const unsigned char* data, size_t size, int variant /*= sodium_base64_VARIANT_ORIGINAL*/) { auto mm = MemoryManager::getInstance(); - size_t binSize = data->size(); - size_t encodedSize = sodium_base64_encoded_len(binSize, sodium_base64_VARIANT_ORIGINAL); - + + size_t encodedSize = sodium_base64_encoded_len(size, variant); auto base64 = mm->getFreeMemory(encodedSize); memset(*base64, 0, encodedSize); size_t resultBinSize = 0; - if (0 != sodium_bin2base64(*base64, encodedSize, *data, binSize, sodium_base64_VARIANT_ORIGINAL)) { + if (nullptr == sodium_bin2base64(*base64, encodedSize, data, size, variant)) { mm->releaseMemory(base64); return ""; } diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index 0dad46954..d970d697d 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -9,6 +9,8 @@ #include "Poco/Data/LOB.h" #include "../SingletonManager/LanguageManager.h" +#include "sodium.h" + namespace DataTypeConverter { enum NumberParseState @@ -25,8 +27,9 @@ namespace DataTypeConverter { MemoryBin* hexToBin(const std::string& hexString); MemoryBin* base64ToBin(const std::string& base64String); - std::string binToBase64(const MemoryBin* data); + std::string binToBase64(const unsigned char* data, size_t size, int variant = sodium_base64_VARIANT_ORIGINAL); + inline std::string binToBase64(const MemoryBin* data, int variant = sodium_base64_VARIANT_ORIGINAL) { return binToBase64(data->data(), data->size(), variant); } std::string binToHex(const unsigned char* data, size_t size); std::string binToHex(const Poco::Nullable& nullableBin); diff --git a/src/cpp/lib/Error.cpp b/src/cpp/lib/Error.cpp index c44f48711..9897d7930 100644 --- a/src/cpp/lib/Error.cpp +++ b/src/cpp/lib/Error.cpp @@ -2,7 +2,7 @@ Error::Error(const char* functionName, const char* message) - : mFunctionName(functionName), mMessage(message) + : Notification(functionName, message) { } @@ -12,7 +12,7 @@ Error::~Error() } -std::string Error::getString(bool withNewline/* = true*/) +std::string Error::getString(bool withNewline/* = true*/) const { std::stringstream ss; ss << mFunctionName << ": " << mMessage; @@ -20,7 +20,7 @@ std::string Error::getString(bool withNewline/* = true*/) return ss.str(); } -std::string Error::getHtmlString() +std::string Error::getHtmlString() const { std::stringstream ss; ss << mFunctionName << ": " << mMessage; @@ -28,7 +28,7 @@ std::string Error::getHtmlString() return ss.str(); } -std::string ParamError::getString(bool withNewline/* = true*/) +std::string ParamError::getString(bool withNewline/* = true*/) const { std::stringstream ss; ss << mFunctionName << ": " << mMessage << " " << mParam; @@ -36,7 +36,7 @@ std::string ParamError::getString(bool withNewline/* = true*/) return ss.str(); } -std::string ParamError::getHtmlString() +std::string ParamError::getHtmlString() const { std::stringstream ss; ss << mFunctionName << ": " << mMessage << " " << mParam << std::endl; diff --git a/src/cpp/lib/Error.h b/src/cpp/lib/Error.h index 2a4d79e85..bf4805da9 100644 --- a/src/cpp/lib/Error.h +++ b/src/cpp/lib/Error.h @@ -1,63 +1,65 @@ -/*! -* -* \author: einhornimmond -* -* \date: 07.03.19 -* -* \brief: error data -*/ - -#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_H -#define DR_LUA_WEB_MODULE_ERROR_ERROR_H - -#include -#include - -class Error -{ -public: - Error(const char* functionName, const char* message); - ~Error(); - - const char* getFunctionName() { return mFunctionName.data(); } - const char* getMessage() { return mMessage.data(); } - virtual std::string getString(bool withNewline = true); - virtual std::string getHtmlString(); - - - -protected: - std::string mFunctionName; - std::string mMessage; -}; - -class ParamError : public Error -{ -public: - ParamError(const char* functionName, const char* message, const char* param) - : Error(functionName, message), mParam(param) {} - ParamError(const char* functionName, const char* message, const std::string& param) - : Error(functionName, message), mParam(param) {} - - ParamError(const char* functioName, const char* message, int param) - : Error(functioName, message) { - std::stringstream ss; - ss << param; - mParam = ss.str(); - } - - virtual std::string getString(bool withNewline = true); - virtual std::string getHtmlString(); -protected: - std::string mParam; -}; - - - -class IErrorCollection -{ -public: - virtual void addError(Error*, bool log = true) = 0; -}; - -#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_H +/*! +* +* \author: einhornimmond +* +* \date: 07.03.19 +* +* \brief: error data +*/ + +#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_H +#define DR_LUA_WEB_MODULE_ERROR_ERROR_H + +#include "Notification.h" +#include +#include + + +class Error : public Notification +{ +public: + Error(const char* functionName, const char* message); + ~Error(); + + const char* getFunctionName() { return mFunctionName.data(); } + const char* getMessage() { return mMessage.data(); } + virtual std::string getString(bool withNewline = true) const; + virtual std::string getHtmlString() const; + + virtual bool isError() { return true; } + +protected: + std::string mFunctionName; + std::string mMessage; +}; + +class ParamError : public Error +{ +public: + ParamError(const char* functionName, const char* message, const char* param) + : Error(functionName, message), mParam(param) {} + ParamError(const char* functionName, const char* message, const std::string& param) + : Error(functionName, message), mParam(param) {} + + ParamError(const char* functioName, const char* message, int param) + : Error(functioName, message) { + std::stringstream ss; + ss << param; + mParam = ss.str(); + } + + virtual std::string getString(bool withNewline = true) const; + virtual std::string getHtmlString() const; +protected: + std::string mParam; +}; + + + +class INotificationCollection +{ +public: + virtual void addError(Notification*, bool log = true) = 0; +}; + +#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_H diff --git a/src/cpp/lib/JsonRequest.cpp b/src/cpp/lib/JsonRequest.cpp index 3e05fa85a..c5dff9281 100644 --- a/src/cpp/lib/JsonRequest.cpp +++ b/src/cpp/lib/JsonRequest.cpp @@ -37,7 +37,6 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::Net:: try { Profiler phpRequestTime; Poco::Net::HTTPSClientSession httpsClientSession(mServerHost, mServerPort); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); request.setChunkedTransferEncoding(true); @@ -101,5 +100,95 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::Net:: return JSON_REQUEST_CONNECT_ERROR; } + return JSON_REQUEST_RETURN_OK; +} +#include "Poco/JSON/Stringifier.h" +JsonRequestReturn JsonRequest::requestGRPCRelay(const Poco::Net::NameValueCollection& payload) +{ + static const char* functionName = "JsonRequest::requestGRPCRelay"; + Poco::JSON::Object requestJson; + + for (auto it = payload.begin(); it != payload.end(); it++) { + requestJson.set(it->first, it->second); + } + + // send post request via https + // 443 = HTTPS Default + // TODO: adding port into ServerConfig + try { + Profiler phpRequestTime; + Poco::Net::HTTPClientSession httpClientSession(mServerHost, mServerPort); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/hedera_rpc_relay/gRPCProxy.php"); + + request.setChunkedTransferEncoding(false); + std::ostream& requestStream = httpClientSession.sendRequest(request); + requestJson.stringify(requestStream); + + std::stringstream ss; + requestJson.stringify(ss); + auto f = fopen("grpc.txt", "wt"); + std::string grpc = ss.str(); + fwrite(grpc.data(), grpc.size(), 1, f); + fclose(f); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = httpClientSession.receiveResponse(response); + + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + Poco::Logger& speedLog = Poco::Logger::get("SpeedLog"); + speedLog.information("[gRPC relay] php server time: %s", phpRequestTime.string()); + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + } + catch (Poco::Exception& ex) { + addError(new ParamError(functionName, "error parsing request answer grpc relay", ex.displayText().data())); + + std::string fileName = "response_grpc_"; + fileName += ".html"; + + FILE* f = fopen(fileName.data(), "wt"); + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + // */ + sendErrorsAsEmail(responseStringStream.str()); + return JSON_REQUEST_RETURN_PARSE_ERROR; + } + + Poco::JSON::Object object = *parsedJson.extract(); + auto state = object.get("state"); + std::string stateString = state.convert(); + if (stateString == "error") { + addError(new Error(functionName, "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError(functionName, "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError(functionName, "details:", object.get("details").convert().data())); + } + sendErrorsAsEmail(); + return JSON_REQUEST_RETURN_ERROR; + } + ss.clear(); + Poco::JSON::Stringifier::stringify(object, ss); + printf("json request result: %s\n", ss.str().data()); + } + catch (Poco::Exception& e) { + addError(new ParamError(functionName, "connect error to php server", e.displayText().data())); + sendErrorsAsEmail(); + return JSON_REQUEST_CONNECT_ERROR; + } + + + return JSON_REQUEST_RETURN_OK; } \ No newline at end of file diff --git a/src/cpp/lib/JsonRequest.h b/src/cpp/lib/JsonRequest.h index 87350c002..e13046594 100644 --- a/src/cpp/lib/JsonRequest.h +++ b/src/cpp/lib/JsonRequest.h @@ -8,7 +8,7 @@ * */ -#include "ErrorList.h" +#include "NotificationList.h" #include "Poco/Net/NameValueCollection.h" #ifndef __GRADIDO_LOGIN_SERVER_LIB_JSON_REQUEST_ @@ -22,17 +22,19 @@ enum JsonRequestReturn JSON_REQUEST_CONNECT_ERROR }; -class JsonRequest : public ErrorList +class JsonRequest : public NotificationList { public: JsonRequest(const std::string& serverHost, int serverPort); ~JsonRequest(); JsonRequestReturn request(const char* methodName, const Poco::Net::NameValueCollection& payload); + JsonRequestReturn requestGRPCRelay(const Poco::Net::NameValueCollection& payload); protected: int mServerPort; std::string mServerHost; + }; diff --git a/src/cpp/lib/MultithreadContainer.cpp b/src/cpp/lib/MultithreadContainer.cpp index fc72593a1..d73a6a882 100644 --- a/src/cpp/lib/MultithreadContainer.cpp +++ b/src/cpp/lib/MultithreadContainer.cpp @@ -1,5 +1,5 @@ #include "MultithreadContainer.h" -#include "ErrorList.h" +#include "NotificationList.h" namespace UniLib { namespace lib { @@ -14,7 +14,7 @@ namespace UniLib { } } catch (Poco::TimeoutException& ex) { - ErrorList errors; + NotificationList errors; errors.addError(new ParamError(functionName, "lock timeout", ex.displayText())); if (mLastSucceededLock != "") { errors.addError(new ParamError(functionName, "last succeed lock by ", mLastSucceededLock.data())); diff --git a/src/cpp/lib/Notification.cpp b/src/cpp/lib/Notification.cpp new file mode 100644 index 000000000..15d622923 --- /dev/null +++ b/src/cpp/lib/Notification.cpp @@ -0,0 +1,7 @@ +#include "Notification.h" + +Notification::Notification(const char* functionName, const char* message) + : mFunctionName(functionName), mMessage(message) +{ + +} \ No newline at end of file diff --git a/src/cpp/lib/Notification.h b/src/cpp/lib/Notification.h new file mode 100644 index 000000000..419b861bc --- /dev/null +++ b/src/cpp/lib/Notification.h @@ -0,0 +1,24 @@ +#ifndef GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H +#define GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H + +#include + +class Notification +{ +public: + Notification(const char* functionName, const char* message); + + const char* getFunctionName() { return mFunctionName.data(); } + const char* getMessage() { return mMessage.data(); } + virtual std::string getString(bool withNewline = true) const = 0; + virtual std::string getHtmlString() const = 0; + + virtual bool isError() { return false; } + virtual bool isSuccess() { return false; } + +protected: + std::string mFunctionName; + std::string mMessage; +}; + +#endif //GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H \ No newline at end of file diff --git a/src/cpp/lib/ErrorList.cpp b/src/cpp/lib/NotificationList.cpp similarity index 74% rename from src/cpp/lib/ErrorList.cpp rename to src/cpp/lib/NotificationList.cpp index a663b67b2..e355d1597 100644 --- a/src/cpp/lib/ErrorList.cpp +++ b/src/cpp/lib/NotificationList.cpp @@ -1,201 +1,215 @@ -#include "ErrorList.h" - -#include "../ServerConfig.h" - -//#include "Poco/Net/MailMessage.h" -#include "Poco/Net/MediaType.h" - -#include "../SingletonManager/EmailManager.h" - -SendErrorMessage::~SendErrorMessage() -{ - if (mMessage) { - delete mMessage; - mMessage = nullptr; - } -} - -int SendErrorMessage::run() -{ - if (ServerConfig::g_disableEmail) return 0; - - auto mailClientSession = new Poco::Net::SecureSMTPClientSession(ServerConfig::g_EmailAccount.url, ServerConfig::g_EmailAccount.port); - mailClientSession->login(); - mailClientSession->startTLS(ServerConfig::g_SSL_CLient_Context); - - - mailClientSession->login(Poco::Net::SMTPClientSession::AUTH_LOGIN, ServerConfig::g_EmailAccount.username, ServerConfig::g_EmailAccount.password); - - try { - mMessage->setSender(ServerConfig::g_EmailAccount.sender); - mailClientSession->sendMessage(*mMessage); - mailClientSession->close(); - } - catch (Poco::Exception& exc) { - printf("[SendErrorMessage::%s] error sending error message to admin: %s\n", - __FUNCTION__, exc.displayText().data()); - return -1; - } - return 0; -} - -// ------------------------------------------------------------------------------------ - - -ErrorList::ErrorList() - : mLogging(Poco::Logger::get("errorLog")) -{ - -} - -ErrorList::~ErrorList() -{ - while (mErrorStack.size() > 0) { - delete mErrorStack.top(); - mErrorStack.pop(); - } -} - -void ErrorList::addError(Error* error, bool log/* = true */) -{ - - if (log) { - std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); - mLogging.error("%s [ErrorList::addError] %s", dateTimeString, error->getString(false)); - - } - mErrorStack.push(error); -} - -Error* ErrorList::getLastError() -{ - if (mErrorStack.size() == 0) { - return nullptr; - } - - Error* error = mErrorStack.top(); - if (error) { - mErrorStack.pop(); - } - - return error; -} - -void ErrorList::clearErrors() -{ - while (mErrorStack.size()) { - auto error = mErrorStack.top(); - if (error) { - delete error; - } - mErrorStack.pop(); - } -} - - -int ErrorList::getErrors(ErrorList* send) -{ - Error* error = nullptr; - int iCount = 0; - while (error = send->getLastError()) { - addError(error, false); - iCount++; - } - return iCount; -} - -void ErrorList::printErrors() -{ - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - printf(error->getString().data()); - delete error; - } -} - -std::vector ErrorList::getErrorsArray() -{ - std::vector result; - result.reserve(mErrorStack.size()); - - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - //result->add(error->getString()); - result.push_back(error->getString()); - delete error; - } - return result; -} - -std::string ErrorList::getErrorsHtml() -{ - std::string res; - res = "
      "; - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - res += "
    • "; - res += error->getHtmlString(); - res += "
    • "; - delete error; - } - res += "
    "; - return res; -} - -std::string ErrorList::getErrorsHtmlNewFormat() -{ - std::string html; - - while (mErrorStack.size() > 0) { - auto error = std::unique_ptr(mErrorStack.top()); - mErrorStack.pop(); - html += "
    "; - html += "report_problem"; - html += ""; - html += error->getHtmlString(); - html += ""; - html += "
    "; - } - return html; -} -/* - -*/ - - -void ErrorList::sendErrorsAsEmail(std::string rawHtml/* = ""*/) -{ - auto em = EmailManager::getInstance(); - /*auto message = new Poco::Net::MailMessage(); - message->setSender("gradido_loginServer@gradido.net"); - message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, "***REMOVED***")); - message->setSubject("Error from Gradido Login Server"); - */ - std::string content; - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - content += error->getString(); - delete error; - } - auto email = new model::Email(content, model::EMAIL_ERROR); - - //message->addContent(new Poco::Net::StringPartSource(content)); - if (rawHtml != "") { - Poco::Net::MediaType mt("text", "html"); - mt.setParameter("charset", "utf-8"); - - email->addContent(new Poco::Net::StringPartSource(rawHtml, mt.toString())); - } - em->addEmail(email); - - //UniLib::controller::TaskPtr sendErrorMessageTask(new SendErrorMessage(message, ServerConfig::g_CPUScheduler)); - //sendErrorMessageTask->scheduleTask(sendErrorMessageTask); - +#include "NotificationList.h" + +#include "../ServerConfig.h" + +//#include "Poco/Net/MailMessage.h" +#include "Poco/Net/MediaType.h" + +#include "../SingletonManager/EmailManager.h" + +SendErrorMessage::~SendErrorMessage() +{ + if (mMessage) { + delete mMessage; + mMessage = nullptr; + } +} + +int SendErrorMessage::run() +{ + if (ServerConfig::g_disableEmail) return 0; + + auto mailClientSession = new Poco::Net::SecureSMTPClientSession(ServerConfig::g_EmailAccount.url, ServerConfig::g_EmailAccount.port); + mailClientSession->login(); + mailClientSession->startTLS(ServerConfig::g_SSL_CLient_Context); + + + mailClientSession->login(Poco::Net::SMTPClientSession::AUTH_LOGIN, ServerConfig::g_EmailAccount.username, ServerConfig::g_EmailAccount.password); + + try { + mMessage->setSender(ServerConfig::g_EmailAccount.sender); + mailClientSession->sendMessage(*mMessage); + mailClientSession->close(); + } + catch (Poco::Exception& exc) { + printf("[SendErrorMessage::%s] error sending error message to admin: %s\n", + __FUNCTION__, exc.displayText().data()); + return -1; + } + return 0; +} + +// ------------------------------------------------------------------------------------ + + +NotificationList::NotificationList() + : mLogging(Poco::Logger::get("errorLog")) +{ + +} + +NotificationList::~NotificationList() +{ + while (mErrorStack.size() > 0) { + delete mErrorStack.top(); + mErrorStack.pop(); + } +} + +void NotificationList::addError(Notification* error, bool log/* = true */) +{ + + if (log) { + std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); + mLogging.error("%s [ErrorList::addError] %s", dateTimeString, error->getString(false)); + + } + mErrorStack.push(error); +} + +void NotificationList::addNotification(Notification* notification) +{ + mErrorStack.push(notification); +} + +Notification* NotificationList::getLastError() +{ + if (mErrorStack.size() == 0) { + return nullptr; + } + + Notification* error = mErrorStack.top(); + if (error) { + mErrorStack.pop(); + } + + return error; +} + +void NotificationList::clearErrors() +{ + while (mErrorStack.size()) { + auto error = mErrorStack.top(); + if (error) { + delete error; + } + mErrorStack.pop(); + } +} + + +int NotificationList::getErrors(NotificationList* send) +{ + Notification* error = nullptr; + int iCount = 0; + while (error = send->getLastError()) { + addError(error, false); + iCount++; + } + return iCount; +} + +void NotificationList::printErrors() +{ + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + printf(error->getString().data()); + delete error; + } +} + +std::vector NotificationList::getErrorsArray() +{ + std::vector result; + result.reserve(mErrorStack.size()); + + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + //result->add(error->getString()); + result.push_back(error->getString()); + delete error; + } + return result; +} + +std::string NotificationList::getErrorsHtml() +{ + std::string res; + res = "
      "; + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + if (error->isError()) { + res += "
    • "; + } + else if (error->isSuccess()) { + res += "
    • "; + } + res += error->getHtmlString(); + res += "
    • "; + delete error; + } + res += "
    "; + return res; +} + +std::string NotificationList::getErrorsHtmlNewFormat() +{ + std::string html; + + while (mErrorStack.size() > 0) { + auto error = std::unique_ptr(mErrorStack.top()); + mErrorStack.pop(); + if (error->isError()) { + html += "
    "; + html += "report_problem"; + } + else if (error->isSuccess()) { + html += "
    "; + } + html += ""; + html += error->getHtmlString(); + html += ""; + html += "
    "; + } + return html; +} +/* + +*/ + + +void NotificationList::sendErrorsAsEmail(std::string rawHtml/* = ""*/) +{ + auto em = EmailManager::getInstance(); + /*auto message = new Poco::Net::MailMessage(); + message->setSender("gradido_loginServer@gradido.net"); + message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, "***REMOVED***")); + message->setSubject("Error from Gradido Login Server"); + */ + std::string content; + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + content += error->getString(); + delete error; + } + auto email = new model::Email(content, model::EMAIL_ERROR); + + //message->addContent(new Poco::Net::StringPartSource(content)); + if (rawHtml != "") { + Poco::Net::MediaType mt("text", "html"); + mt.setParameter("charset", "utf-8"); + + email->addContent(new Poco::Net::StringPartSource(rawHtml, mt.toString())); + } + em->addEmail(email); + + //UniLib::controller::TaskPtr sendErrorMessageTask(new SendErrorMessage(message, ServerConfig::g_CPUScheduler)); + //sendErrorMessageTask->scheduleTask(sendErrorMessageTask); } \ No newline at end of file diff --git a/src/cpp/lib/ErrorList.h b/src/cpp/lib/NotificationList.h similarity index 74% rename from src/cpp/lib/ErrorList.h rename to src/cpp/lib/NotificationList.h index d2913a241..a3b2edcf1 100644 --- a/src/cpp/lib/ErrorList.h +++ b/src/cpp/lib/NotificationList.h @@ -1,76 +1,74 @@ -/*! -* -* \author: einhornimmond -* -* \date: 07.03.19 -* -* \brief: error -*/ - -#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H -#define DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H - -#include "Error.h" -#include - -#include "../tasks/CPUTask.h" - -#include "Poco/Net/SecureSMTPClientSession.h" -#include "Poco/Net/StringPartSource.h" -#include "Poco/Logger.h" -#include "Poco/JSON/Array.h" - -class ErrorList : public IErrorCollection -{ -public: - ErrorList(); - ~ErrorList(); - - // push error, error will be deleted in deconstructor - virtual void addError(Error* error, bool log = true); - - // return error on top of stack, please delete after using - Error* getLastError(); - - inline size_t errorCount() { return mErrorStack.size(); } - - // delete all errors - void clearErrors(); - - static int moveErrors(ErrorList* recv, ErrorList* send) { - return recv->getErrors(send); - } - int getErrors(ErrorList* send); - - void printErrors(); - std::string getErrorsHtml(); - std::string getErrorsHtmlNewFormat(); - - std::vector getErrorsArray(); - - void sendErrorsAsEmail(std::string rawHtml = ""); - -protected: - std::stack mErrorStack; - // poco logging - Poco::Logger& mLogging; -}; - -class SendErrorMessage : public UniLib::controller::CPUTask -{ -public: - SendErrorMessage(Poco::Net::MailMessage* message, UniLib::controller::CPUSheduler* scheduler) - : UniLib::controller::CPUTask(scheduler), mMessage(message) {} - - ~SendErrorMessage(); - - virtual int run(); - const char* getResourceType() const { return "SendErrorMessage"; }; - - -protected: - Poco::Net::MailMessage* mMessage; - -}; - -#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H +/*! +* +* \author: einhornimmond +* +* \date: 07.03.19 +* +* \brief: error +*/ + +#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H +#define DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H + +#include "Error.h" +#include + +#include "../tasks/CPUTask.h" + +#include "Poco/Net/SecureSMTPClientSession.h" +#include "Poco/Net/StringPartSource.h" +#include "Poco/Logger.h" + +class NotificationList : public INotificationCollection +{ +public: + NotificationList(); + ~NotificationList(); + + // push error, error will be deleted in deconstructor + virtual void addError(Notification* error, bool log = true); + void addNotification(Notification* notification); + + // return error on top of stack, please delete after using + Notification* getLastError(); + + inline size_t errorCount() { return mErrorStack.size(); } + + // delete all errors + void clearErrors(); + + static int moveErrors(NotificationList* recv, NotificationList* send) { + return recv->getErrors(send); + } + int getErrors(NotificationList* send); + + void printErrors(); + std::string getErrorsHtml(); + std::string getErrorsHtmlNewFormat(); + + void sendErrorsAsEmail(std::string rawHtml = ""); + +protected: + std::stack mErrorStack; + // poco logging + Poco::Logger& mLogging; +}; + +class SendErrorMessage : public UniLib::controller::CPUTask +{ +public: + SendErrorMessage(Poco::Net::MailMessage* message, UniLib::controller::CPUSheduler* scheduler) + : UniLib::controller::CPUTask(scheduler), mMessage(message) {} + + ~SendErrorMessage(); + + virtual int run(); + const char* getResourceType() const { return "SendErrorMessage"; }; + + +protected: + Poco::Net::MailMessage* mMessage; + +}; + +#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H diff --git a/src/cpp/lib/Success.cpp b/src/cpp/lib/Success.cpp new file mode 100644 index 000000000..5cf23f3b8 --- /dev/null +++ b/src/cpp/lib/Success.cpp @@ -0,0 +1,52 @@ +#include "Success.h" +#include + +Success::Success(const char* functionName, const char* message) + : Notification(functionName, message) +{ + +} + +std::string Success::getString(bool withNewline/* = true*/) const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage; + if (withNewline) ss << std::endl; + + return ss.str(); +} +std::string Success::getHtmlString() const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage; + + return ss.str(); +} + +ParamSuccess::ParamSuccess(const char* functionName, const char* message, std::string param) + : Success(functionName, message), mParam(param) +{ + +} + +ParamSuccess::ParamSuccess(const char* functionName, const char* message, int param) + : Success(functionName, message), mParam(std::to_string(param)) +{ + +} + +std::string ParamSuccess::getString(bool withNewline/* = true*/) const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage << " " << mParam; + if (withNewline) ss << std::endl; + + return ss.str(); +} +std::string ParamSuccess::getHtmlString() const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage << " " << mParam; + + return ss.str(); +} \ No newline at end of file diff --git a/src/cpp/lib/Success.h b/src/cpp/lib/Success.h new file mode 100644 index 000000000..4fc4b4fcf --- /dev/null +++ b/src/cpp/lib/Success.h @@ -0,0 +1,30 @@ +#ifndef GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H +#define GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H + +#include "Notification.h" + +class Success : public Notification +{ +public: + Success(const char* functionName, const char* message); + + std::string getString(bool withNewline = true) const; + std::string getHtmlString() const; + + virtual bool isSuccess() { return true; } +}; + +class ParamSuccess : public Success +{ +public: + ParamSuccess(const char* functionName, const char* message, std::string param); + ParamSuccess(const char* functionName, const char* message, int param); + + std::string getString(bool withNewline = true) const; + std::string getHtmlString() const; + +protected: + std::string mParam; +}; + +#endif //GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H \ No newline at end of file diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index ec60b6fc3..b8f2cc949 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -1,282 +1,281 @@ -/*! -* -* \author: einhornimmond -* -* \date: 02.03.19 -* -* \brief: store session data -*/ - -#ifndef DR_LUA_WEB_MODULE_SESSION_SESSION_H -#define DR_LUA_WEB_MODULE_SESSION_SESSION_H - -#include "../lib/ErrorList.h" -#include "User.h" -#include "../controller/User.h" - -#include "../lib/MultithreadContainer.h" -#include "../tasks/ProcessingTransaction.h" - -#include "../SingletonManager/LanguageManager.h" - -#include "../controller/EmailVerificationCode.h" - -#include "Poco/Thread.h" -#include "Poco/Types.h" -#include "Poco/DateTime.h" -#include "Poco/Net/IPAddress.h" -#include "Poco/Net/HTTPCookie.h" - -#include - - -class WriteEmailVerification; - -enum SessionStates { - SESSION_STATE_EMPTY, - SESSION_STATE_CRYPTO_KEY_GENERATED, - SESSION_STATE_USER_WRITTEN, - SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, - SESSION_STATE_EMAIL_VERIFICATION_SEND, - SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED, - SESSION_STATE_PASSPHRASE_GENERATED, - SESSION_STATE_PASSPHRASE_SHOWN, - SESSION_STATE_PASSPHRASE_WRITTEN, - SESSION_STATE_KEY_PAIR_GENERATED, - SESSION_STATE_KEY_PAIR_WRITTEN, - SESSION_STATE_RESET_PASSWORD_REQUEST, - SESSION_STATE_RESET_PASSWORD_SUCCEED, - SESSION_STATE_COUNT -}; - -class SessionManager; - -class UpdateUserPasswordPage; -class PassphrasePage; -class RepairDefectPassphrase; - -class Session : public ErrorList, public UniLib::lib::MultithreadContainer -{ - friend WriteEmailVerification; - friend SessionManager; - friend UpdateUserPasswordPage; - friend PassphrasePage; - friend RepairDefectPassphrase; -public: - Session(int handle); - ~Session(); - - // get new model objects - Poco::AutoPtr getEmailVerificationCodeObject(); - - // set new model objects - inline void setUser(Poco::AutoPtr user) { mNewUser = user; } - inline Poco::AutoPtr getNewUser() { return mNewUser; } - - // ---------------- User functions ---------------------------- - // TODO: register state: written into db, mails sended, update state only if new state is higher as old state - // create User send e-mail activation link - bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); - - //! \brief new register function, without showing user pubkeys, using controller/user - bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); - - - // adminRegister without passwort - bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); - - // TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing - UserStates loadUser(const std::string& email, const std::string& password); - bool ifUserExist(const std::string& email); - - inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } - - - bool deleteUser(); - - Poco::AutoPtr getUser() { - return mSessionUser; - } - - // ------------------------- Email Verification Code functions ------------------------------- - - bool loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode); - - //! \return 1 = konto already exist - //! -1 = invalid code - //! -2 = critical error - //! 0 = ok - int updateEmailVerification(Poco::UInt64 emailVerificationCode); - - // called from page with same name - //! \return 1 = reset password email already send - //! \return 2 = reset password email already shortly before - //! \return 0 = ok - int sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized); - // - //! \return 0 = not the same - //! \return 1 = same - //! \return -1 = error - //! \return -2 = critical error - int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource); - - Poco::Net::HTTPCookie getLoginCookie(); - - - inline int getHandle() { return mHandleId; } - - // ------------------------ Passphrase functions ---------------------------- - - inline void setPassphrase(Poco::AutoPtr passphrase) { mNewPassphrase = passphrase; } - inline Poco::AutoPtr getPassphrase() { return mNewPassphrase; } - - inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; } - - inline const std::string& getOldPassphrase() { return mPassphrase; } - bool generatePassphrase(); - bool generateKeys(bool savePrivkey, bool savePassphrase); - - inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; } - inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; } - - inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; } - bool isPwdValid(const std::string& pwd); - void reset(); - - void updateState(SessionStates newState); - const char* getSessionStateString(); - inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; } - - inline Poco::UInt64 getEmailVerificationCode() { - std::shared_lock _lock(mSharedMutex); - if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode(); - } - inline void setEmailVerificationCodeObject(Poco::AutoPtr emailVerficationObject) { - std::unique_lock _lock(mSharedMutex); - mEmailVerificationCodeObject = emailVerficationObject; - } - inline model::table::EmailOptInType getEmailVerificationType() { - std::shared_lock _lock(mSharedMutex); - if (mEmailVerificationCodeObject.isNull()) { - return model::table::EMAIL_OPT_IN_EMPTY; - } - return mEmailVerificationCodeObject->getModel()->getType(); - } - - //! \return -1 if session is locked - //! \return 1 if session is active - //! \return 0 - int isActive(); - //! \return false if session is locked - bool setActive(bool active); - - bool isDeadLocked(); - - inline Poco::DateTime getLastActivity() { return mLastActivity; } - - // ------------------------ transactions functions ---------------------------- - - //! \return true if succeed - bool startProcessingTransaction(const std::string& proto_message_base64, bool autoSign = false); - //! \param working if set will filled with transaction running - Poco::AutoPtr getNextReadyTransaction(size_t* working = nullptr); - bool finalizeTransaction(bool sign, bool reject); - size_t getProcessingTransactionCount(); - - inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; } - void setLanguage(Languages lang); - inline void setLanguageCatalog(Poco::AutoPtr languageCatalog) { mLanguageCatalog = languageCatalog; } - Languages getLanguage(); - inline const char* gettext(const char* text) { if (mLanguageCatalog.isNull()) return text; return mLanguageCatalog->gettext(text); } - - // last referer - inline void setLastReferer(const std::string& lastReferer) { mLastExternReferer = lastReferer; } - inline const std::string& getLastReferer() const { return mLastExternReferer; } - -protected: - void updateTimeout(); - inline void setHandle(int newHandle) { mHandleId = newHandle; } - - void detectSessionState(); - static const char* translateSessionStateToString(SessionStates state); - - inline const std::string& getPassphrase() const { return mPassphrase; } - - -private: - int mHandleId; - Poco::AutoPtr mSessionUser; - Poco::AutoPtr mNewUser; - std::string mPassphrase; - Poco::AutoPtr mNewPassphrase; - Poco::DateTime mLastActivity; - Poco::Net::IPAddress mClientLoginIP; - std::string mLastExternReferer; - Poco::AutoPtr mEmailVerificationCodeObject; - std::shared_mutex mSharedMutex; - - - SessionStates mState; - - bool mActive; - std::list> mProcessingTransactions; - Poco::AutoPtr mCurrentActiveProcessingTransaction; - - Poco::AutoPtr mLanguageCatalog; -}; - - -class WriteEmailVerification : public UniLib::controller::CPUTask -{ -public: - WriteEmailVerification(Poco::AutoPtr user, Poco::AutoPtr emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) - : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - virtual const char* getResourceType() const { return "WriteEmailVerification"; }; - virtual int run(); - -private: - Poco::AutoPtr mUser; - Poco::AutoPtr mEmailVerificationCode; - -}; - -class WritePassphraseIntoDB : public UniLib::controller::CPUTask -{ -public: - WritePassphraseIntoDB(int userId, const std::string& passphrase) - : mUserId(userId), mPassphrase(passphrase) { -#ifdef _UNI_LIB_DEBUG - setName(std::to_string(userId).data()); -#endif - } - - - virtual int run(); - virtual const char* getResourceType() const { return "WritePassphraseIntoDB"; }; - -protected: - int mUserId; - std::string mPassphrase; -}; - -class SessionStateUpdateCommand : public UniLib::controller::Command -{ -public: - SessionStateUpdateCommand(SessionStates state, Session* session) - : mState(state), mSession(session) {} - virtual int taskFinished(UniLib::controller::Task* task) { - mSession->updateState(mState); - return 0; - } - -protected: - SessionStates mState; - Session* mSession; -}; - -#endif // DR_LUA_WEB_MODULE_SESSION_SESSION_H +/*! +* +* \author: einhornimmond +* +* \date: 02.03.19 +* +* \brief: store session data +*/ + +#ifndef DR_LUA_WEB_MODULE_SESSION_SESSION_H +#define DR_LUA_WEB_MODULE_SESSION_SESSION_H + +#include "../lib/NotificationList.h" +#include "User.h" +#include "../controller/User.h" + +#include "../lib/MultithreadContainer.h" +#include "../tasks/ProcessingTransaction.h" + +#include "../SingletonManager/LanguageManager.h" + +#include "../controller/EmailVerificationCode.h" + +#include "Poco/Thread.h" +#include "Poco/Types.h" +#include "Poco/DateTime.h" +#include "Poco/Net/IPAddress.h" +#include "Poco/Net/HTTPCookie.h" + +#include + + +class WriteEmailVerification; + +enum SessionStates { + SESSION_STATE_EMPTY, + SESSION_STATE_CRYPTO_KEY_GENERATED, + SESSION_STATE_USER_WRITTEN, + SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, + SESSION_STATE_EMAIL_VERIFICATION_SEND, + SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED, + SESSION_STATE_PASSPHRASE_GENERATED, + SESSION_STATE_PASSPHRASE_SHOWN, + SESSION_STATE_PASSPHRASE_WRITTEN, + SESSION_STATE_KEY_PAIR_GENERATED, + SESSION_STATE_KEY_PAIR_WRITTEN, + SESSION_STATE_RESET_PASSWORD_REQUEST, + SESSION_STATE_RESET_PASSWORD_SUCCEED, + SESSION_STATE_COUNT +}; + +class SessionManager; +class UpdateUserPasswordPage; +class PassphrasePage; +class RepairDefectPassphrase; + +class Session : public NotificationList, public UniLib::lib::MultithreadContainer +{ + friend WriteEmailVerification; + friend SessionManager; + friend UpdateUserPasswordPage; + friend PassphrasePage; + friend RepairDefectPassphrase; +public: + Session(int handle); + ~Session(); + + // get new model objects + Poco::AutoPtr getEmailVerificationCodeObject(); + + // set new model objects + inline void setUser(Poco::AutoPtr user) { mNewUser = user; } + inline Poco::AutoPtr getNewUser() { return mNewUser; } + + // ---------------- User functions ---------------------------- + // TODO: register state: written into db, mails sended, update state only if new state is higher as old state + // create User send e-mail activation link + bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + + //! \brief new register function, without showing user pubkeys, using controller/user + bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + + + // adminRegister without passwort + bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); + + // TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing + UserStates loadUser(const std::string& email, const std::string& password); + bool ifUserExist(const std::string& email); + + inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } + + + bool deleteUser(); + + Poco::AutoPtr getUser() { + return mSessionUser; + } + + // ------------------------- Email Verification Code functions ------------------------------- + + bool loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode); + + //! \return 1 = konto already exist + //! -1 = invalid code + //! -2 = critical error + //! 0 = ok + int updateEmailVerification(Poco::UInt64 emailVerificationCode); + + // called from page with same name + //! \return 1 = reset password email already send + //! \return 2 = reset password email already shortly before + //! \return 0 = ok + int sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized); + // + //! \return 0 = not the same + //! \return 1 = same + //! \return -1 = error + //! \return -2 = critical error + int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource); + + Poco::Net::HTTPCookie getLoginCookie(); + + + inline int getHandle() { return mHandleId; } + + // ------------------------ Passphrase functions ---------------------------- + + inline void setPassphrase(Poco::AutoPtr passphrase) { mNewPassphrase = passphrase; } + inline Poco::AutoPtr getPassphrase() { return mNewPassphrase; } + + inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; } + + inline const std::string& getOldPassphrase() { return mPassphrase; } + bool generatePassphrase(); + bool generateKeys(bool savePrivkey, bool savePassphrase); + + inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; } + inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; } + + inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; } + bool isPwdValid(const std::string& pwd); + void reset(); + + void updateState(SessionStates newState); + const char* getSessionStateString(); + inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; } + + inline Poco::UInt64 getEmailVerificationCode() { + std::shared_lock _lock(mSharedMutex); + if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode(); + } + inline void setEmailVerificationCodeObject(Poco::AutoPtr emailVerficationObject) { + std::unique_lock _lock(mSharedMutex); + mEmailVerificationCodeObject = emailVerficationObject; + } + inline model::table::EmailOptInType getEmailVerificationType() { + std::shared_lock _lock(mSharedMutex); + if (mEmailVerificationCodeObject.isNull()) { + return model::table::EMAIL_OPT_IN_EMPTY; + } + return mEmailVerificationCodeObject->getModel()->getType(); + } + + //! \return -1 if session is locked + //! \return 1 if session is active + //! \return 0 + int isActive(); + //! \return false if session is locked + bool setActive(bool active); + + bool isDeadLocked(); + + inline Poco::DateTime getLastActivity() { return mLastActivity; } + + // ------------------------ transactions functions ---------------------------- + + //! \return true if succeed + bool startProcessingTransaction(const std::string& proto_message_base64, bool autoSign = false); + //! \param working if set will filled with transaction running + Poco::AutoPtr getNextReadyTransaction(size_t* working = nullptr); + bool finalizeTransaction(bool sign, bool reject); + size_t getProcessingTransactionCount(); + + inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; } + void setLanguage(Languages lang); + inline void setLanguageCatalog(Poco::AutoPtr languageCatalog) { mLanguageCatalog = languageCatalog; } + Languages getLanguage(); + inline const char* gettext(const char* text) { if (mLanguageCatalog.isNull()) return text; return mLanguageCatalog->gettext(text); } + + // last referer + inline void setLastReferer(const std::string& lastReferer) { mLastExternReferer = lastReferer; } + inline const std::string& getLastReferer() const { return mLastExternReferer; } + +protected: + void updateTimeout(); + inline void setHandle(int newHandle) { mHandleId = newHandle; } + + void detectSessionState(); + static const char* translateSessionStateToString(SessionStates state); + + inline const std::string& getPassphrase() const { return mPassphrase; } + + +private: + int mHandleId; + Poco::AutoPtr mSessionUser; + Poco::AutoPtr mNewUser; + std::string mPassphrase; + Poco::AutoPtr mNewPassphrase; + Poco::DateTime mLastActivity; + Poco::Net::IPAddress mClientLoginIP; + std::string mLastExternReferer; + Poco::AutoPtr mEmailVerificationCodeObject; + std::shared_mutex mSharedMutex; + + + SessionStates mState; + + bool mActive; + std::list> mProcessingTransactions; + Poco::AutoPtr mCurrentActiveProcessingTransaction; + + Poco::AutoPtr mLanguageCatalog; +}; + + +class WriteEmailVerification : public UniLib::controller::CPUTask +{ +public: + WriteEmailVerification(Poco::AutoPtr user, Poco::AutoPtr emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) + : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) { +#ifdef _UNI_LIB_DEBUG + setName(user->getEmail()); +#endif + } + + virtual const char* getResourceType() const { return "WriteEmailVerification"; }; + virtual int run(); + +private: + Poco::AutoPtr mUser; + Poco::AutoPtr mEmailVerificationCode; + +}; + +class WritePassphraseIntoDB : public UniLib::controller::CPUTask +{ +public: + WritePassphraseIntoDB(int userId, const std::string& passphrase) + : mUserId(userId), mPassphrase(passphrase) { +#ifdef _UNI_LIB_DEBUG + setName(std::to_string(userId).data()); +#endif + } + + + virtual int run(); + virtual const char* getResourceType() const { return "WritePassphraseIntoDB"; }; + +protected: + int mUserId; + std::string mPassphrase; +}; + +class SessionStateUpdateCommand : public UniLib::controller::Command +{ +public: + SessionStateUpdateCommand(SessionStates state, Session* session) + : mState(state), mSession(session) {} + virtual int taskFinished(UniLib::controller::Task* task) { + mSession->updateState(mState); + return 0; + } + +protected: + SessionStates mState; + Session* mSession; +}; + +#endif // DR_LUA_WEB_MODULE_SESSION_SESSION_H diff --git a/src/cpp/model/TransactionBase.h b/src/cpp/model/TransactionBase.h index 84406fddb..5bb0bad14 100644 --- a/src/cpp/model/TransactionBase.h +++ b/src/cpp/model/TransactionBase.h @@ -11,11 +11,11 @@ #pragma warning(disable:4800) -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../proto/gradido/BasicTypes.pb.h" #include "../SingletonManager/MemoryManager.h" -class TransactionBase : public ErrorList, public UniLib::lib::MultithreadContainer +class TransactionBase : public NotificationList, public UniLib::lib::MultithreadContainer { public: TransactionBase(const std::string& memo); diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index 80763d337..a57324cf8 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -732,7 +732,7 @@ void User::setEmailChecked() unlock(); } -bool User::validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint) +bool User::validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint) { auto mm = MemoryManager::getInstance(); auto cmpCryptoKey = createCryptoKey(pwd); @@ -935,7 +935,7 @@ MemoryBin* User::createCryptoKey(const std::string& password) return key; } -User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver/* = nullptr*/) +User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver/* = nullptr*/) { if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); diff --git a/src/cpp/model/User.h b/src/cpp/model/User.h index c041cea7d..cc1a8be86 100644 --- a/src/cpp/model/User.h +++ b/src/cpp/model/User.h @@ -4,7 +4,7 @@ #include "../Crypto/KeyPair.h" #include //#include "ModelBase.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "Poco/Thread.h" #include "Poco/Types.h" @@ -50,7 +50,7 @@ enum UserFields USER_FIELDS_LANGUAGE }; -class User : public ErrorList +class User : public NotificationList { friend UserCreateCryptoKey; friend UserWriteIntoDB; @@ -115,7 +115,7 @@ public: bool isEmptyPassword(); //bool setNewPassword(const std::string& newPassword); bool updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser); - bool validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint); + bool validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint); bool validateIdentHash(HASH hash); MemoryBin* encrypt(const MemoryBin* data); @@ -134,7 +134,7 @@ protected: typedef Poco::UInt64 passwordHashed; MemoryBin* createCryptoKey(const std::string& password); - static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver = nullptr); + static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver = nullptr); inline void setCryptoKey(MemoryBin* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); } //void detectState(); diff --git a/src/cpp/model/email/Email.h b/src/cpp/model/email/Email.h index d2887a26c..0fc52cac0 100644 --- a/src/cpp/model/email/Email.h +++ b/src/cpp/model/email/Email.h @@ -17,7 +17,7 @@ #include "../../SingletonManager/LanguageManager.h" -#include "../../lib/ErrorList.h" +#include "../../lib/NotificationList.h" namespace model { using namespace Poco; @@ -39,7 +39,7 @@ namespace model { EMAIL_MAX }; - class Email: public ErrorList + class Email: public NotificationList { public: Email(AutoPtr emailVerification, AutoPtr user, EmailType type); diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.cpp b/src/cpp/model/hedera/CryptoTransferTransaction.cpp new file mode 100644 index 000000000..828a85645 --- /dev/null +++ b/src/cpp/model/hedera/CryptoTransferTransaction.cpp @@ -0,0 +1,53 @@ +#include "CryptoTransferTransaction.h" + +namespace model { + namespace hedera { + + CryptoTransferTransaction::CryptoTransferTransaction() + : mCryptoTransfer(nullptr) + { + mCryptoTransfer = new proto::CryptoTransferTransactionBody; + } + + CryptoTransferTransaction::~CryptoTransferTransaction() + { + if (mCryptoTransfer) { + delete mCryptoTransfer; + mCryptoTransfer = nullptr; + } + } + + void CryptoTransferTransaction::addSender(Poco::AutoPtr senderAccountId, Poco::UInt64 amountTinybars) + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto accountAmounts = transfers->add_accountamounts(); + accountAmounts->set_amount(-(Poco::Int64)amountTinybars); + senderAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid()); + } + void CryptoTransferTransaction::addReceiver(Poco::AutoPtr receiverAccountId, Poco::UInt64 amountTinybars) + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto accountAmounts = transfers->add_accountamounts(); + accountAmounts->set_amount(amountTinybars); + receiverAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid()); + } + + bool CryptoTransferTransaction::validate() + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto account_amounts = transfers->accountamounts(); + Poco::Int64 sum = 0; + for (int i = 0; i < transfers->accountamounts_size(); i++) { + auto account_amount = account_amounts.Mutable(i); + sum += account_amount->amount(); + } + return 0 == sum && transfers->accountamounts_size() > 0; + } + + void CryptoTransferTransaction::resetPointer() + { + mCryptoTransfer = nullptr; + } + } +} + diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.h b/src/cpp/model/hedera/CryptoTransferTransaction.h new file mode 100644 index 000000000..04aacafea --- /dev/null +++ b/src/cpp/model/hedera/CryptoTransferTransaction.h @@ -0,0 +1,40 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for creating a hedera transfer transaction +* +*/ + +#include "../../proto/hedera/CryptoTransfer.pb.h" +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + class CryptoTransferTransaction + { + public: + CryptoTransferTransaction(); + ~CryptoTransferTransaction(); + + void addSender(Poco::AutoPtr senderAccountId, Poco::UInt64 amountTinybars); + void addReceiver(Poco::AutoPtr receiverAccountId, Poco::UInt64 amountTinybars); + + bool validate(); + // set pointer to zero, after hand over pointer to transaction body + void resetPointer(); + + inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; } + + protected: + proto::CryptoTransferTransactionBody* mCryptoTransfer; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index 39b3700c4..de4fdec99 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -2,18 +2,24 @@ #include "Poco/Timestamp.h" #include "../../SingletonManager/MemoryManager.h" +#include "Transaction.h" +#include "TransactionBody.h" +#include "CryptoTransferTransaction.h" + namespace model { namespace hedera { Query::Query(const controller::NodeServerConnection& connection) - : mConnection(connection) + : mConnection(connection), mTransactionBody(nullptr) { } Query::~Query() { - + if (mTransactionBody) { + delete mTransactionBody; + } } Query* Query::getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection) @@ -26,58 +32,46 @@ namespace model { accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); query_header->set_responsetype(proto::COST_ANSWER); - auto transaction = query_header->mutable_payment(); + + query->mTransactionBody = new TransactionBody(accountId, connection); + CryptoTransferTransaction crypto_transaction; + crypto_transaction.addSender(accountId, 0); + crypto_transaction.addReceiver(connection.hederaId, 0); + query->mTransactionBody->setCryptoTransfer(crypto_transaction); + + //auto transaction = query_header->mutable_payment(); //auto transaction_body = transaction->mutable_body(); // body content - // transaction id - auto transaction_id = query->mTransactionBody.mutable_transactionid(); - auto timestamp = transaction_id->mutable_transactionvalidstart(); - Poco::Timestamp now; - auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 - timestamp->set_seconds(now.epochTime()); - timestamp->set_nanos(microseconds * 1000); - accountId->copyToProtoAccountId(transaction_id->mutable_accountid()); - // - // sdk default, but can be changed - query->mTransactionBody.set_transactionfee(100000000); - auto valid_duration = query->mTransactionBody.mutable_transactionvalidduration(); - // maximal 2 minutes - valid_duration->set_seconds(120); - auto crypto_transfer = query->mTransactionBody.mutable_cryptotransfer(); - auto transfer_list = crypto_transfer->mutable_transfers(); - auto account_amounts = transfer_list->mutable_accountamounts(); - account_amounts->Add(); - auto account_amount = account_amounts->Mutable(0); - account_amount->set_amount(1000); - connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); + // node account id + return query; } bool Query::sign(std::unique_ptr keyPairHedera) { - auto mm = MemoryManager::getInstance(); - auto body_bytes = mTransactionBody.SerializeAsString(); - auto transaction = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header()->mutable_payment(); - transaction->set_bodybytes(body_bytes.data()); - auto signature_map = transaction->mutable_sigmap(); - auto signature_pairs = signature_map->mutable_sigpair(); - signature_pairs->Add(); - auto signature_pair = signature_pairs->Mutable(0); - auto public_key = keyPairHedera->getPublicKey(); + Transaction transaction; + auto sign_result = transaction.sign(std::move(keyPairHedera), mTransactionBody); + auto query_header = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header(); + query_header->set_allocated_payment(transaction.getTransaction()); + transaction.resetPointer(); - - auto sign = keyPairHedera->sign(body_bytes); - if (!sign) { - printf("[Query::sign] error signing message\n"); - return false; - } - signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); - signature_pair->set_ed25519(*sign, sign->size()); + return sign_result; + } - mm->releaseMemory(sign); + void Query::setResponseType(proto::ResponseType type) + { + auto get_account_balance = mQueryProto.mutable_cryptogetaccountbalance(); + auto query_header = get_account_balance->mutable_header(); + query_header->set_responsetype(type); - return true; + } + + proto::ResponseType Query::getResponseType() + { + auto get_account_balance = mQueryProto.mutable_cryptogetaccountbalance(); + auto query_header = get_account_balance->mutable_header(); + return query_header->responsetype(); } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index ad9af855a..fa9b06471 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -13,6 +13,7 @@ #include "../../proto/hedera/Query.pb.h" #include "../../controller/NodeServer.h" #include "../../Crypto/KeyPairHedera.h" +#include "TransactionBody.h" namespace model { namespace hedera { @@ -23,13 +24,16 @@ namespace model { static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); bool sign(std::unique_ptr keyPairHedera); + void setResponseType(proto::ResponseType type); + proto::ResponseType getResponseType(); + void setFee(Poco::UInt64 fee); inline const proto::Query* getProtoQuery() const { return &mQueryProto; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } protected: Query(const controller::NodeServerConnection& connection); proto::Query mQueryProto; - proto::TransactionBody mTransactionBody; + TransactionBody* mTransactionBody; controller::NodeServerConnection mConnection; }; } diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp index e69de29bb..a39c5364e 100644 --- a/src/cpp/model/hedera/Response.cpp +++ b/src/cpp/model/hedera/Response.cpp @@ -0,0 +1,32 @@ +#include "Response.h" + +namespace model { + namespace hedera { + Response::Response() + { + } + + Response::~Response() + { + + } + + Poco::UInt64 Response::getAccountBalance() + { + if (isCryptoGetAccountBalanceResponse()) { + auto balance_response = mResponseProto.cryptogetaccountbalance(); + return balance_response.balance(); + } + return 0; + } + + proto::ResponseCodeEnum Response::getResponseCode() + { + if (isCryptoGetAccountBalanceResponse()) { + auto balance_response = mResponseProto.cryptogetaccountbalance(); + return balance_response.header().nodetransactionprecheckcode(); + } + return proto::NOT_SUPPORTED; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h index e69de29bb..779f5e982 100644 --- a/src/cpp/model/hedera/Response.h +++ b/src/cpp/model/hedera/Response.h @@ -0,0 +1,38 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H + +/*! +* @author: Dario Rekowski +* +* @date: 03.09.20 +* +* @brief: class for simply accessing hedera responses +* +*/ + +#include "../../proto/hedera/Response.pb.h" +#include "Poco/Types.h" + +namespace model { + namespace hedera { + class Response + { + public: + Response(); + ~Response(); + + inline proto::Response* getResponsePtr() { return &mResponseProto; } + Poco::UInt64 getAccountBalance(); + proto::ResponseCodeEnum getResponseCode(); + + inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); } + + protected: + proto::Response mResponseProto; + + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index e69de29bb..0dadbcb4c 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -0,0 +1,43 @@ +#include "Transaction.h" + +namespace model { + namespace hedera { + Transaction::Transaction() + : mTransaction(nullptr) + { + mTransaction = new proto::Transaction; + } + + Transaction::~Transaction() + { + if (mTransaction) { + delete mTransaction; + mTransaction = nullptr; + } + } + + bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) + { + auto mm = MemoryManager::getInstance(); + auto transaction_body_proto = transactionBody->getProtoTransactionBody(); + auto body_bytes = transaction_body_proto->SerializeAsString(); + mTransaction->set_bodybytes(body_bytes.data()); + auto signature_map = mTransaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_map->add_sigpair(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + return true; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index e69de29bb..3acf46ff9 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -0,0 +1,38 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing hedera transaction +* +*/ + +#include "../../proto/hedera/Transaction.pb.h" +#include "../../Crypto/KeyPairHedera.h" +#include "TransactionBody.h" + +namespace model { + namespace hedera { + class Transaction + { + public: + Transaction(); + ~Transaction(); + + bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); + + inline proto::Transaction* getTransaction() { return mTransaction; } + void resetPointer() { mTransaction = nullptr; } + + protected: + + proto::Transaction* mTransaction; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index e69de29bb..f1979b6bf 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -0,0 +1,47 @@ +#include "TransactionBody.h" + +namespace model { + namespace hedera { + TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) + { + connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); + auto transaction_id = mTransactionBody.mutable_transactionid(); + operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid()); + mTransactionBody.set_transactionfee(10000); + auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration(); + transaction_valid_duration->set_seconds(120); + + updateTimestamp(); + } + + TransactionBody::~TransactionBody() + { + + } + + bool TransactionBody::setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction) + { + if (cryptoTransferTransaction.validate()) { + mTransactionBody.set_allocated_cryptotransfer(cryptoTransferTransaction.getProtoTransactionBody()); + cryptoTransferTransaction.resetPointer(); + return true; + } + return false; + } + + void TransactionBody::setMemo(const std::string& memo) + { + mTransactionBody.set_memo(memo); + } + + void TransactionBody::updateTimestamp() + { + auto transaction_id = mTransactionBody.mutable_transactionid(); + auto timestamp = transaction_id->mutable_transactionvalidstart(); + Poco::Timestamp now; + auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 + timestamp->set_seconds(now.epochTime()); + timestamp->set_nanos(microseconds * 1000); + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index e69de29bb..3663c4a59 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -0,0 +1,39 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing transaction body for hedera transaction +* +*/ + +#include "../../proto/hedera/TransactionBody.pb.h" +#include "../../controller/NodeServer.h" +#include "CryptoTransferTransaction.h" + +namespace model { + namespace hedera { + class TransactionBody + { + public: + TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection); + ~TransactionBody(); + + void setMemo(const std::string& memo); + + bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + + inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } + + protected: + void updateTimestamp(); + proto::TransactionBody mTransactionBody; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H \ No newline at end of file diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 9a1e823fe..62ff4958a 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -24,7 +24,7 @@ namespace model { MYSQL_CONDITION_OR }; - class ModelBase : public UniLib::lib::MultithreadContainer, public ErrorList + class ModelBase : public UniLib::lib::MultithreadContainer, public NotificationList { public: ModelBase(int id) :mID(id), mReferenceCount(1) {} diff --git a/src/cpp/tasks/ProcessingTransaction.h b/src/cpp/tasks/ProcessingTransaction.h index 9886bac8a..269cde176 100644 --- a/src/cpp/tasks/ProcessingTransaction.h +++ b/src/cpp/tasks/ProcessingTransaction.h @@ -3,7 +3,7 @@ #include "CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/DRHash.h" #include "../model/TransactionBase.h" @@ -28,7 +28,7 @@ class TransactionCreation; class TransactionTransfer; class SigningTransaction; -class ProcessingTransaction : public UniLib::controller::CPUTask, public ErrorList +class ProcessingTransaction : public UniLib::controller::CPUTask, public NotificationList { friend SigningTransaction; public: diff --git a/src/cpp/tasks/SigningTransaction.h b/src/cpp/tasks/SigningTransaction.h index 2038c0669..aaedbea0d 100644 --- a/src/cpp/tasks/SigningTransaction.h +++ b/src/cpp/tasks/SigningTransaction.h @@ -1,46 +1,45 @@ -#ifndef GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE -#define GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE - -#include "CPUTask.h" - -#include "../lib/ErrorList.h" -#include "../model/TransactionBase.h" -#include "../model/User.h" -#include "../controller/User.h" - -#include "../proto/gradido/Transaction.pb.h" - -#include "ProcessingTransaction.h" - -/* -* @author: Dario Rekowski -* -* @date: 28.10.19 -* @desc: Task for signing Transactions -*/ - -class SigningTransaction : public UniLib::controller::CPUTask, public ErrorList -{ -public: - SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser, bool sendErrorsToAdmin = true); - virtual ~SigningTransaction(); - - int run(); - - const char* getResourceType() const { return "SigningTransaction"; }; - - - -protected: - Poco::AutoPtr mProcessingeTransaction; - Poco::AutoPtr mNewUser; - bool mSendErrorsToAdminEmail; - -private: - - std::string getUserEmail(); - -}; - - +#ifndef GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE +#define GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE + +#include "CPUTask.h" + +#include "../lib/NotificationList.h" +#include "../model/TransactionBase.h" +#include "../model/User.h" +#include "../controller/User.h" + +#include "../proto/gradido/Transaction.pb.h" + +#include "ProcessingTransaction.h" + +/* +* @author: Dario Rekowski +* +* @date: 28.10.19 +* @desc: Task for signing Transactions +*/ + +class SigningTransaction : public UniLib::controller::CPUTask, public NotificationList +{ +public: + SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser); + virtual ~SigningTransaction(); + + int run(); + + const char* getResourceType() const { return "SigningTransaction"; }; + + + +protected: + Poco::AutoPtr mProcessingeTransaction; + Poco::AutoPtr mNewUser; + bool mSendErrorsToAdminEmail; + +private: + + std::string getUserEmail(); + +}; + #endif //GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE \ No newline at end of file diff --git a/src/cpp/tasks/Task.cpp b/src/cpp/tasks/Task.cpp index e75b1a53d..07bb4c3fc 100644 --- a/src/cpp/tasks/Task.cpp +++ b/src/cpp/tasks/Task.cpp @@ -1,5 +1,5 @@ #include "Task.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" namespace UniLib { namespace controller { @@ -87,7 +87,7 @@ namespace UniLib { mWorkingMutex.lock(500); } catch (Poco::TimeoutException& ex) { - ErrorList errors; + NotificationList errors; errors.addError(new ParamError("Task::lock", getResourceType(), ex.displayText())); errors.sendErrorsAsEmail(); } diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 5379e4ef4..3e8795d24 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -10,6 +10,8 @@ #include "../controller/HederaId.h" #include "../controller/CryptoKey.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/Success.h" #include "../SingletonManager/SessionManager.h" #include "../ServerConfig.h" @@ -22,6 +24,8 @@ auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Profiler hedera_time; + std::string hedera_time_string; Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); @@ -44,7 +48,9 @@ if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { + hedera_time.reset(); hedera_account[0]->updateBalanceFromHedera(user, this); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } } @@ -148,6 +154,7 @@ %><%@ include file="header_large.cpsp" %> <%= getErrorsHtml() %> +
    From 266ef2c92a507eab0f20ebec2b473efe4e66678b Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 9 Sep 2020 19:34:00 +0200 Subject: [PATCH 073/195] updates for hedera transactions and saving crypto keys also clear un-encrypted --- skeema/gradido_login/hedera_topics.sql | 1 + src/cpp/Crypto/KeyPairHedera.cpp | 42 ++-- src/cpp/Crypto/KeyPairHedera.h | 8 +- .../HTTPInterface/AdminHederaAccountPage.cpp | 5 +- src/cpp/HTTPInterface/AdminTopicPage.cpp | 180 ++++++++++++++---- src/cpp/controller/CryptoKey.cpp | 62 ++++-- src/cpp/controller/CryptoKey.h | 6 +- src/cpp/controller/HederaAccount.cpp | 12 +- src/cpp/controller/HederaAccount.h | 4 +- src/cpp/controller/HederaRequest.cpp | 12 ++ src/cpp/controller/HederaRequest.h | 1 + src/cpp/controller/HederaTopic.cpp | 26 +++ src/cpp/controller/HederaTopic.h | 38 ++++ src/cpp/main.cpp | 16 +- src/cpp/model/hedera/ConsensusCreateTopic.cpp | 45 +++++ src/cpp/model/hedera/ConsensusCreateTopic.h | 31 +++ .../model/hedera/CryptoCreateTransaction.cpp | 16 ++ .../model/hedera/CryptoCreateTransaction.h | 23 +++ src/cpp/model/hedera/Query.cpp | 6 +- src/cpp/model/hedera/Query.h | 7 +- src/cpp/model/hedera/Transaction.cpp | 1 + src/cpp/model/hedera/Transaction.h | 3 +- src/cpp/model/hedera/TransactionBody.cpp | 15 ++ src/cpp/model/hedera/TransactionBody.h | 9 +- src/cpp/model/table/CryptoKey.cpp | 25 ++- src/cpp/model/table/CryptoKey.h | 12 +- src/cpp/model/table/HederaAccount.cpp | 1 + src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaTopic.cpp | 17 +- src/cpp/model/table/HederaTopic.h | 14 ++ src/cpsp/adminHederaAccount.cpsp | 5 +- src/cpsp/adminTopic.cpsp | 112 ++++++++++- 32 files changed, 651 insertions(+), 105 deletions(-) create mode 100644 src/cpp/controller/HederaTopic.cpp create mode 100644 src/cpp/controller/HederaTopic.h create mode 100644 src/cpp/model/hedera/CryptoCreateTransaction.cpp create mode 100644 src/cpp/model/hedera/CryptoCreateTransaction.h diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index 02f7e3b39..b9adaefc2 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -1,6 +1,7 @@ CREATE TABLE `hedera_topics` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `topic_hedera_id` int unsigned NOT NULL, + `name` VARCHAR(255) NOT NULL DEFAULT '', `auto_renew_account_hedera_id` int unsigned DEFAULT NULL, `auto_renew_period` int unsigned NOT NULL DEFAULT '0', `group_id` int unsigned NOT NULL, diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 27d9731a7..62643cc99 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -10,7 +10,7 @@ KeyPairHedera::KeyPairHedera() } -KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) +KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) : mPrivateKey(nullptr) { auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420"); @@ -19,27 +19,28 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* p auto mm = MemoryManager::getInstance(); if (privateKey) { - switch (privateKey->size()) { + switch (privateKeySize) { case 48: // key with prefix - if (0 == sodium_memcmp(*privateKey, *derPrefixPriv, derPrefixPriv->size())) { + if (0 == sodium_memcmp(privateKey, *derPrefixPriv, derPrefixPriv->size())) { //int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed); auto seed = mm->getFreeMemory(crypto_sign_ed25519_SEEDBYTES); - memcpy(*seed, privateKey->data(derPrefixPriv->size()), crypto_sign_ed25519_SEEDBYTES); - createKeyFromSeed(seed); + memcpy(*seed, &privateKey[derPrefixPriv->size()], crypto_sign_ed25519_SEEDBYTES); + createKeyFromSeed(seed->data(), seed->size()); + mm->releaseMemory(seed); break; } case 32: - createKeyFromSeed(privateKey); + createKeyFromSeed(privateKey, privateKeySize); break; case 64: //mPrivateKey = privateKey; - if (!mPrivateKey || mPrivateKey->size() != privateKey->size()) { + if (!mPrivateKey || mPrivateKey->size() != privateKeySize) { if (mPrivateKey) { mm->releaseMemory(mPrivateKey); } - mPrivateKey = mm->getFreeMemory(privateKey->size()); - memcpy(*mPrivateKey, *privateKey, privateKey->size()); + mPrivateKey = mm->getFreeMemory(privateKeySize); + memcpy(*mPrivateKey, privateKey, privateKeySize); } break; default: @@ -75,11 +76,17 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* p mm->releaseMemory(derPrefixPub); } KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/) - : KeyPairHedera(privateKey, publicKey->data(), publicKey->size()) + : KeyPairHedera(privateKey->data(), privateKey->size(), publicKey->data(), publicKey->size()) { } +KeyPairHedera::KeyPairHedera(const std::vector& privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/) + : KeyPairHedera(privateKey.data(), privateKey.size(), publicKey, publicKeySize) +{ + +} + KeyPairHedera::~KeyPairHedera() { auto mm = MemoryManager::getInstance(); @@ -90,13 +97,13 @@ KeyPairHedera::~KeyPairHedera() } -void KeyPairHedera::createKeyFromSeed(const MemoryBin* seed) +void KeyPairHedera::createKeyFromSeed(const unsigned char* seed, size_t seedSize) { - assert(seed && seed->size() == crypto_sign_ed25519_SEEDBYTES); + assert(seed && seedSize == crypto_sign_ed25519_SEEDBYTES); auto mm = MemoryManager::getInstance(); auto secret_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES); - crypto_sign_seed_keypair(mPublicKey, *secret_key, *seed); + crypto_sign_seed_keypair(mPublicKey, *secret_key, seed); if (mPrivateKey) { mm->releaseMemory(mPrivateKey); @@ -177,6 +184,15 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtrgetFreeMemory(mPrivateKey->size()); + memcpy(*private_key_copy, *mPrivateKey, mPrivateKey->size()); + return private_key_copy; +} + MemoryBin* KeyPairHedera::getPublicKeyCopy() const { auto mm = MemoryManager::getInstance(); diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index a3e4337e5..b308cbe9e 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -22,8 +22,9 @@ public: //! \param privateKey: copy //! \param publicKey: copy //! - KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); + KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); + KeyPairHedera(const std::vector& privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); ~KeyPairHedera(); @@ -64,13 +65,14 @@ public: inline bool hasPrivateKey() const { return mPrivateKey != nullptr; } - //! \brief only way to get a private key.. encrypted + //! \brief MemoryBin* getCryptedPrivKey(const Poco::AutoPtr password) const; + MemoryBin* getPrivateKeyCopy() const; protected: KeyPairHedera(); - void createKeyFromSeed(const MemoryBin* seed); + void createKeyFromSeed(const unsigned char* seed, size_t seedSize); private: diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index fa99a7b35..54a416bef 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -70,7 +70,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request addError(new Error("Action Update Balance", "hedera id not found")); } else { hedera_time.reset(); - hedera_account[0]->updateBalanceFromHedera(user, this); + hedera_account[0]->hederaAccountGetBalance(user, this); addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } @@ -318,7 +318,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request #line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( gettext("Add Account") ); responseStream << "\">\n"; - responseStream << "\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t
    \n"; responseStream << "
    \n"; // begin include footer.cpsp responseStream << "
    \n"; diff --git a/src/cpp/HTTPInterface/AdminTopicPage.cpp b/src/cpp/HTTPInterface/AdminTopicPage.cpp index d8926093e..66fb252d7 100644 --- a/src/cpp/HTTPInterface/AdminTopicPage.cpp +++ b/src/cpp/HTTPInterface/AdminTopicPage.cpp @@ -7,8 +7,10 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" - -#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + #include "../controller/HederaAccount.h" + #include "../controller/Group.h" + #include "../ServerConfig.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" #include "../ServerConfig.h" @@ -27,20 +29,34 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 12 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" const char* pageName = "Topic"; + auto user = mSession->getNewUser(); + + int auto_renew_period = 604800; // 7 Tage + int auto_renew_account = 0; + int group_id = 0; + + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); + + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } - -#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" bool withMaterialIcons = false; std::ostream& _responseStream = response.send(); Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; responseStream << "\n"; - // begin include header_large.cpsp + // begin include header.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; @@ -48,57 +64,132 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << "\n"; responseStream << "\n"; responseStream << "Gradido Login Server: "; -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" responseStream << ( pageName ); responseStream << "\n"; responseStream << "\n"; -#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" if(withMaterialIcons) { responseStream << "\n"; responseStream << "\n"; -#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" } responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "
    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t
    "; - // end include header_large.cpsp + responseStream << "
    \n"; + responseStream << " "; + // end include header.cpsp responseStream << "\n"; -#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + responseStream << "\n"; +#line 40 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t

    Topic Admin Page

    \n"; responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "\t\n"; + responseStream << "
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t

    Ein neues Topic anlegen

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t
    \n"; responseStream << "
    \n"; // begin include footer.cpsp responseStream << "
    \n"; @@ -124,5 +215,18 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << ""; // end include footer.cpsp responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; if (_compressResponse) _gzipStream.close(); } diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index 79d68a62e..aa8df1b8d 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -15,16 +15,25 @@ namespace controller { } - Poco::AutoPtr CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user) + Poco::AutoPtr CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user, bool saveEncrypted/* = true*/) { auto mm = MemoryManager::getInstance(); - auto encrypted_priv_key = hederaKeyPair->getCryptedPrivKey(user->getPassword()); + MemoryBin* private_key = nullptr; auto public_key = hederaKeyPair->getPublicKeyCopy(); - auto db = new model::table::CryptoKey(encrypted_priv_key, public_key, model::table::KEY_TYPE_ED25519_HEDERA); + model::table::KeyType key_type; + if (saveEncrypted) { + key_type = model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED; + private_key = hederaKeyPair->getCryptedPrivKey(user->getPassword()); + } + else { + key_type = model::table::KEY_TYPE_ED25519_HEDERA_CLEAR; + private_key = hederaKeyPair->getPrivateKeyCopy(); + } + auto db = new model::table::CryptoKey(private_key, public_key, key_type); - mm->releaseMemory(encrypted_priv_key); + mm->releaseMemory(private_key); mm->releaseMemory(public_key); auto cryptoKey = new CryptoKey(db); @@ -63,28 +72,49 @@ namespace controller { return nullptr; } - std::unique_ptr CryptoKey::getKeyPair(Poco::AutoPtr user) + std::unique_ptr CryptoKey::getKeyPair(Poco::AutoPtr user) const { auto model = getModel(); - auto password = user->getPassword(); - auto mm = MemoryManager::getInstance(); - if (!password || !model->hasPrivateKeyEncrypted()) { - printf("[CryptoKey::getKeyPair] return null, password empty or no private key\n"); + assert(model); + + if (!model->isEncrypted()) { + return getKeyPair(); + } + + if (!model->hasPrivateKey()) { + printf("[CryptoKey::getKeyPair] return null, no private key\n"); return nullptr; } - MemoryBin* clearPassword = nullptr; - auto encrypted_private_key = model->getPrivateKeyEncrypted(); - auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key); - printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data()); - if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) { + + auto password = user->getPassword(); + auto mm = MemoryManager::getInstance(); + if (!password) { + printf("[CryptoKey::getKeyPair] return null, password empty\n"); + } + MemoryBin* clearPrivateKey = nullptr; + auto encrypted_private_key = model->getPrivateKey(); + //auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key); + //printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data()); + if (password->decrypt(model->getPrivateKey(), &clearPrivateKey) != SecretKeyCryptography::AUTH_DECRYPT_OK) { printf("[CryptoKey::getKeyPair] return null, error decrypting\n"); return nullptr; } - auto key_pair = std::make_unique(clearPassword, model->getPublicKey(), model->getPublicKeySize()); - mm->releaseMemory(clearPassword); + auto key_pair = std::make_unique(clearPrivateKey->data(), clearPrivateKey->size(), model->getPublicKey(), model->getPublicKeySize()); + mm->releaseMemory(clearPrivateKey); return key_pair; } + std::unique_ptr CryptoKey::getKeyPair() const + { + auto model = getModel(); + assert(model); + if (!model->hasPrivateKey() || model->isEncrypted()) { + printf("[CryptoKey::getKeyPair] no private key or encrypted\n"); + return nullptr; + } + + return std::make_unique(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize()); + } } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index fc69d042c..ef48c88f1 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -16,7 +16,7 @@ namespace controller { ~CryptoKey(); - static Poco::AutoPtr create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user); + static Poco::AutoPtr create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr user, bool saveEncrypted = true); //! if returned ptr is NULL, dataset not found static Poco::AutoPtr load(int id); @@ -26,8 +26,10 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::CryptoKey* getModel() const { return _getModel(); } - std::unique_ptr getKeyPair(Poco::AutoPtr user); + std::unique_ptr getKeyPair(Poco::AutoPtr user) const; + std::unique_ptr getKeyPair() const; protected: diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 6fabe2848..e4873ecf0 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) + bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -132,5 +132,15 @@ namespace controller { return false; } + + std::string HederaAccount::toShortSelectOptionName() + { + std::stringstream ss; + auto model = getModel(); + ss << model::table::HederaAccount::hederaNetworkTypeToString((model::table::HederaNetworkType)model->getNetworkType()) << " "; + ss << mHederaID->getModel()->toString() << " " << ((double)model->getBalance() / 100000000.0) << " Hbar"; + return ss.str(); + } + } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index d76420b78..a9a53d528 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -22,12 +22,14 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + std::string HederaAccount::toShortSelectOptionName(); + inline Poco::AutoPtr getModel() { return _getModel(); } inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); + bool hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 308ffa5e8..64998fa6a 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -59,6 +59,18 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::h return HEDERA_REQUEST_RETURN_OK; } +HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, model::hedera::Response* response) +{ + auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials()); + + grpc::ClientContext context; + std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + + std::chrono::milliseconds(5000); + context.set_deadline(deadline); + + return HEDERA_REQUEST_RETURN_OK; +} + #include "Poco/JSON/Object.h" #include "../lib/JsonRequest.h" diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 327ee7634..34bd304a1 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -31,6 +31,7 @@ public: ~HederaRequest(); HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); + HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response); //! for testing, didn't work server say invalid json :/ HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp new file mode 100644 index 000000000..3885c31d8 --- /dev/null +++ b/src/cpp/controller/HederaTopic.cpp @@ -0,0 +1,26 @@ +#include "HederaTopic.h" +#include "../model/hedera/Transaction.h" + +namespace controller { + HederaTopic::HederaTopic(model::table::HederaTopic* dbModel) + { + mDBModel = dbModel; + } + HederaTopic::~HederaTopic() + { + + } + + Poco::AutoPtr HederaTopic::create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId) + { + auto db = new model::table::HederaTopic(name, autoRenewAccountId, autoRenewPeriod, groupId); + + auto hedera_topic = new HederaTopic(db); + return Poco::AutoPtr(hedera_topic); + } + + Poco::UInt64 HederaTopic::hederaCreateTopic() + { + + } +} \ No newline at end of file diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h new file mode 100644 index 000000000..de5552e39 --- /dev/null +++ b/src/cpp/controller/HederaTopic.h @@ -0,0 +1,38 @@ +#ifndef __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H +#define __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H + +/*! +* +* \author: Dario Rekowski +* +* \date: 03.09.2020 +* +* \brief: Class for Hedera Topic, connct db table with hedera object +* +*/ +#include "TableControllerBase.h" +#include "../model/table/HederaTopic.h" + +namespace controller { + class HederaTopic : public TableControllerBase + { + public: + + ~HederaTopic(); + + static Poco::AutoPtr create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId); + + //! \brief hedera call to create a hedera topic + Poco::UInt64 hederaCreateTopic(); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + HederaTopic(model::table::HederaTopic* dbModel); + + }; + +#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H \ No newline at end of file diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 910db09ff..899779fef 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -45,17 +45,25 @@ int main(int argc, char** argv) printf("[Gradido_LoginServer::main] error loading mnemonic Word List"); return -2; } + printf("[Gradido_LoginServer::main] mnemonic word lists loaded!\n"); if (!ImportantTests::passphraseGenerationAndTransformation()) { printf("test passphrase generation and transformation failed\n"); return -3; } + printf("[Gradido_LoginServer::main] passed important tests\n"); grpc_init(); Gradido_LoginServer app; - auto result = app.run(argc, argv); - - grpc_shutdown(); - return result; + try { + auto result = app.run(argc, argv); + grpc_shutdown(); + return result; + } + catch (Poco::Exception& ex) { + printf("[Gradido_LoginServer::main] exception by starting server: %s\n", ex.displayText().data()); + } + return -1; + } #endif \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp index e69de29bb..6ca423102 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.cpp +++ b/src/cpp/model/hedera/ConsensusCreateTopic.cpp @@ -0,0 +1,45 @@ +#include "ConsensusCreateTopic.h" + +namespace model { + namespace hedera { + ConsensusCreateTopic::ConsensusCreateTopic(Poco::AutoPtr autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod) + : mProtoCreateTopic(nullptr) + { + mProtoCreateTopic = new proto::ConsensusCreateTopicTransactionBody; + auto auto_renew_period = mProtoCreateTopic->mutable_autorenewperiod(); + auto_renew_period->set_seconds(autoRenewPeriod); + + auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount(); + autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account); + + } + ConsensusCreateTopic::~ConsensusCreateTopic() + { + if (mProtoCreateTopic) { + delete mProtoCreateTopic; + mProtoCreateTopic = nullptr; + } + } + + void ConsensusCreateTopic::setAdminKey(const MemoryBin* adminPublicKey) + { + auto admin_key = mProtoCreateTopic->mutable_adminkey(); + auto admin_key_string = admin_key->mutable_ed25519(); + *admin_key_string = std::string((const char)*adminPublicKey, adminPublicKey->size()); + } + void ConsensusCreateTopic::setSubmitKey(const MemoryBin* submitPublicKey) + { + auto submit_key = mProtoCreateTopic->mutable_submitkey(); + auto submit_key_string = submit_key->mutable_ed25519(); + *submit_key_string = std::string((const char)*submitPublicKey, submitPublicKey->size()); + } + + bool ConsensusCreateTopic::validate() + { + if (mProtoCreateTopic->autorenewperiod().seconds() > 86400 && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) { + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.h b/src/cpp/model/hedera/ConsensusCreateTopic.h index e69de29bb..e61da46f3 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.h +++ b/src/cpp/model/hedera/ConsensusCreateTopic.h @@ -0,0 +1,31 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H + +#include "../../proto/hedera/ConsensusCreateTopic.pb.h" +#include "../../SingletonManager/MemoryManager.h" + +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + class ConsensusCreateTopic + { + public: + ConsensusCreateTopic(Poco::AutoPtr autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod); + ~ConsensusCreateTopic(); + + inline void setMemo(const std::string& memo) { mProtoCreateTopic->set_memo(memo); } + void setAdminKey(const MemoryBin* adminPublicKey); + void setSubmitKey(const MemoryBin* submitPublicKey); + + bool validate(); + + inline proto::ConsensusCreateTopicTransactionBody* getProtoTransactionBody() { return mProtoCreateTopic; } + inline void resetPointer() { mProtoCreateTopic = nullptr; } + protected: + proto::ConsensusCreateTopicTransactionBody* mProtoCreateTopic; + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.cpp b/src/cpp/model/hedera/CryptoCreateTransaction.cpp new file mode 100644 index 000000000..696a8d6e7 --- /dev/null +++ b/src/cpp/model/hedera/CryptoCreateTransaction.cpp @@ -0,0 +1,16 @@ +#include "CryptoCreateTransaction.h" + +namespace model { + namespace hedera { + + CryptoCreateTransaction::CryptoCreateTransaction() + { + } + + CryptoCreateTransaction::~CryptoCreateTransaction() + { + + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.h b/src/cpp/model/hedera/CryptoCreateTransaction.h new file mode 100644 index 000000000..e1425ebf5 --- /dev/null +++ b/src/cpp/model/hedera/CryptoCreateTransaction.h @@ -0,0 +1,23 @@ +#ifndef __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H +#define __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H + +#include "../../proto/hedera/CryptoCreate.pb.h" + +namespace model { + namespace hedera { + + class CryptoCreateTransaction + { + public: + CryptoCreateTransaction(); + ~CryptoCreateTransaction(); + + protected: + proto::CryptoCreateTransactionBody* mCryptoCreateBody; + }; + } +} + + + +#endif //__GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index de4fdec99..11a8eb735 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -9,8 +9,8 @@ namespace model { namespace hedera { - Query::Query(const controller::NodeServerConnection& connection) - : mConnection(connection), mTransactionBody(nullptr) + Query::Query() + : mTransactionBody(nullptr) { } @@ -27,7 +27,7 @@ namespace model { assert(!accountId.isNull() && accountId->getModel()); - auto query = new Query(connection); + auto query = new Query; auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance(); accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index fa9b06471..376528314 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -26,15 +26,14 @@ namespace model { void setResponseType(proto::ResponseType type); proto::ResponseType getResponseType(); - void setFee(Poco::UInt64 fee); + inline const proto::Query* getProtoQuery() const { return &mQueryProto; } - inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } + inline std::string getConnectionString() const { return mTransactionBody->getConnectionString(); } protected: - Query(const controller::NodeServerConnection& connection); + Query(); proto::Query mQueryProto; TransactionBody* mTransactionBody; - controller::NodeServerConnection mConnection; }; } } diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index 0dadbcb4c..4699e71ea 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -19,6 +19,7 @@ namespace model { bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) { auto mm = MemoryManager::getInstance(); + mConnection = transactionBody->getConnection(); auto transaction_body_proto = transactionBody->getProtoTransactionBody(); auto body_bytes = transaction_body_proto->SerializeAsString(); mTransaction->set_bodybytes(body_bytes.data()); diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index 3acf46ff9..d5e9434bd 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -25,11 +25,12 @@ namespace model { bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); inline proto::Transaction* getTransaction() { return mTransaction; } + inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } void resetPointer() { mTransaction = nullptr; } protected: - proto::Transaction* mTransaction; + controller::NodeServerConnection mConnection; }; } } diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index f1979b6bf..f215ada23 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -3,6 +3,7 @@ namespace model { namespace hedera { TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) + : mConnection(connection) { connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); auto transaction_id = mTransactionBody.mutable_transactionid(); @@ -29,10 +30,24 @@ namespace model { return false; } + bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction) + { + if (consensusCreateTopicTransaction.validate()) { + mTransactionBody.set_allocated_consensuscreatetopic(consensusCreateTopicTransaction.getProtoTransactionBody()); + consensusCreateTopicTransaction.resetPointer(); + return true; + } + return false; + } + void TransactionBody::setMemo(const std::string& memo) { mTransactionBody.set_memo(memo); } + void TransactionBody::setFee(Poco::UInt64 fee) + { + mTransactionBody.set_transactionfee(fee); + } void TransactionBody::updateTimestamp() { diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 3663c4a59..ba421e014 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -13,6 +13,7 @@ #include "../../proto/hedera/TransactionBody.pb.h" #include "../../controller/NodeServer.h" #include "CryptoTransferTransaction.h" +#include "ConsensusCreateTopic.h" namespace model { namespace hedera { @@ -23,14 +24,20 @@ namespace model { ~TransactionBody(); void setMemo(const std::string& memo); - + void setFee(Poco::UInt64 fee); + bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction); + //bool inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } + inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } + inline controller::NodeServerConnection getConnection() const { return mConnection; } protected: void updateTimestamp(); proto::TransactionBody mTransactionBody; + controller::NodeServerConnection mConnection; }; } } diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index 9588f57e7..a4f1034e3 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -43,12 +43,33 @@ namespace model { const char* CryptoKey::typeToString(KeyType type) { switch (type) { - case KEY_TYPE_ED25519_SODIUM: return "ed25519 ref10"; - case KEY_TYPE_ED25519_HEDERA: return "sodium ed22519"; + case KEY_TYPE_ED25519_SODIUM_ENCRYPTED: return "ed25519 sodium encrypted"; + case KEY_TYPE_ED25519_HEDERA_ENCRYPTED: return "ed22519 for hedera encrypted"; + case KEY_TYPE_ED25519_SODIUM_CLEAR: return "ed25519 sodium clear"; + case KEY_TYPE_ED25519_HEDERA_CLEAR: return "ed25519 hedera clear"; } return ""; } + bool CryptoKey::hasPrivateKeyEncrypted() const + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED || type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + return !mPrivateKey.isNull(); + } + return false; + } + + bool CryptoKey::isEncrypted() const + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED || + type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + return true; + } + return false; + } + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index 7e50fc728..c1fa0b66d 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -8,8 +8,10 @@ namespace model { namespace table { enum KeyType { - KEY_TYPE_ED25519_SODIUM = 0, - KEY_TYPE_ED25519_HEDERA = 1, + KEY_TYPE_ED25519_SODIUM_ENCRYPTED = 0, + KEY_TYPE_ED25519_HEDERA_ENCRYPTED = 1, + KEY_TYPE_ED25519_SODIUM_CLEAR = 2, + KEY_TYPE_ED25519_HEDERA_CLEAR = 3, KEY_TYPE_COUNT }; @@ -27,8 +29,10 @@ namespace model { inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } - inline bool hasPrivateKeyEncrypted() const { return !mPrivateKey.isNull(); } - inline const std::vector& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); } + bool hasPrivateKeyEncrypted() const; + bool isEncrypted() const; + inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); } + inline const std::vector& getPrivateKey() const { return mPrivateKey.value().content(); } static const char* typeToString(KeyType type); protected: diff --git a/src/cpp/model/table/HederaAccount.cpp b/src/cpp/model/table/HederaAccount.cpp index 1485ff554..2479c09cc 100644 --- a/src/cpp/model/table/HederaAccount.cpp +++ b/src/cpp/model/table/HederaAccount.cpp @@ -44,6 +44,7 @@ namespace model { return ss.str(); } + const char* HederaAccount::hederaNetworkTypeToString(HederaNetworkType type) { switch (type) { diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 4d4dd6575..6b0d636a0 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -28,6 +28,7 @@ namespace model { // generic db operations const char* getTableName() const { return "hedera_accounts"; } std::string toString(); + static const char* hederaNetworkTypeToString(HederaNetworkType type); static NodeServerType networkTypeToNodeServerType(HederaNetworkType type); diff --git a/src/cpp/model/table/HederaTopic.cpp b/src/cpp/model/table/HederaTopic.cpp index ef80ea071..b91ea0864 100644 --- a/src/cpp/model/table/HederaTopic.cpp +++ b/src/cpp/model/table/HederaTopic.cpp @@ -5,6 +5,14 @@ using namespace Poco::Data::Keywords; namespace model { namespace table { HederaTopic::HederaTopic() + : mTopicHederaId(0), mAutoRenewAccountHederaId(0), mAutoRenewPeriod(0), mGroupId(0), mAdminKeyId(0), mSubmitKeyId(0),mSequenceNumber(0) + { + + } + + HederaTopic::HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId) + : mTopicHederaId(0), mName(name), mAutoRenewAccountHederaId(autoRenewAccountId), mAutoRenewPeriod(autoRenewAccountId), mGroupId(groupId), + mAdminKeyId(0), mSubmitKeyId(0), mSequenceNumber(0) { } @@ -18,6 +26,7 @@ namespace model { { std::stringstream ss; ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl; + ss << "Name: " << mName << std::endl; ss << "Auto Renew Account Hedera id: " << std::to_string(mAutoRenewAccountHederaId) << std::endl; ss << "Auto Renew Period: " << std::to_string(mAutoRenewPeriod) << " seconds" << std::endl; ss << "Group id: " << std::to_string(mGroupId) << std::endl; @@ -33,10 +42,10 @@ namespace model { { Poco::Data::Statement select(session); - select << "SELECT id, topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period, " + select << "SELECT id, topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period, " << "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName() << " where " << fieldName << " = ?" - , into(mID), into(mTopicHederaId), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod) + , into(mID), into(mTopicHederaId), into(mName), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod) , into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated); return select; @@ -57,9 +66,9 @@ namespace model { Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period," + << " (topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period," << " group_id, admin_key_id, submit_key_id, current_timeout, sequence_number) VALUES(?,?,?,?,?,?,?,?)" - , use(mTopicHederaId), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod) + , use(mTopicHederaId), use(mName), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod) , use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber), use(mUpdated); unlock(); return insert; diff --git a/src/cpp/model/table/HederaTopic.h b/src/cpp/model/table/HederaTopic.h index fe5cc342b..3c8cb6f16 100644 --- a/src/cpp/model/table/HederaTopic.h +++ b/src/cpp/model/table/HederaTopic.h @@ -10,12 +10,25 @@ namespace model { { public: HederaTopic(); + HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId); ~HederaTopic(); // generic db operations const char* getTableName() const { return "hedera_topics"; } std::string toString(); + inline Poco::UInt32 getTopicHederaId() const { return mTopicHederaId; } + inline std::string getName() const { return mName; } + inline Poco::UInt32 getAutoRenewAccountId() const { return mAutoRenewAccountHederaId; } + inline Poco::UInt32 getAutoRenewPeriod() const { return mAutoRenewPeriod; } + inline Poco::UInt32 getGroupId() const { return mGroupId;} + inline Poco::DateTime getCurrentTimoout() const { return mCurrentTimeout; } + inline Poco::UInt64 getSequenceNumber() const { return mSequenceNumber; } + inline Poco::DateTime getUpdated() const { return mUpdated; } + + inline void setTopicHederaID(Poco::UInt32 topidHederaId) { mTopicHederaId = topidHederaId;} + inline void setSequeceNumber(Poco::UInt64 sequenceNumber) { mSequenceNumber = sequenceNumber; } + inline void setCurrentTimeout(Poco::DateTime currentTimeOut) { mCurrentTimeout = currentTimeOut; } protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); @@ -23,6 +36,7 @@ namespace model { Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); Poco::UInt32 mTopicHederaId; + std::string mName; Poco::UInt32 mAutoRenewAccountHederaId; // in seconds Poco::UInt32 mAutoRenewPeriod; diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 3e8795d24..95d6992b7 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -49,7 +49,7 @@ addError(new Error("Action Update Balance", "hedera id not found")); } else { hedera_time.reset(); - hedera_account[0]->updateBalanceFromHedera(user, this); + hedera_account[0]->hederaAccountGetBalance(user, this); addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } @@ -204,6 +204,7 @@ <% } %> "> - + +
    <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/adminTopic.cpsp b/src/cpsp/adminTopic.cpsp index 3eac5a976..ffef4ea18 100644 --- a/src/cpsp/adminTopic.cpsp +++ b/src/cpsp/adminTopic.cpsp @@ -5,19 +5,123 @@ <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> <%! - + #include "../controller/HederaAccount.h" + #include "../controller/Group.h" + #include "../SingletonManager/SessionManager.h" + #include "../ServerConfig.h" + #include "../lib/DataTypeConverter.h" %> <%% const char* pageName = "Topic"; + auto user = mSession->getNewUser(); + auto sm = SessionManager::getInstance(); + + std::string name = ""; + int auto_renew_account = 0; + int auto_renew_period = 604800; // 7 Tage + + int group_id = 0; + if(!form.empty()) { + name = form.get("topic-name", ""); + auto auto_renew_account_string = form.get("topic-auto-renew-account", "0"); + auto auto_renew_period_string = form.get("topic-auto-renew-period", "604800"); + auto group_id_string = form.get("topic-group", "-1"); + + if(name != "" && !sm->isValid(name, VALIDATE_NAME)) { + addError(new Error("Topic", "Name not valid, at least 3 Character")); + } + + if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Topic", "auto renew account id not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew account id to int")); + } + } + + if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Topic", "auto renew period not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew period to int")); + } + } -%><%@ include file="header_large.cpsp" %> + if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Topic", "group_id not an integer")); + } else { + if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting group_id to int")); + } + } + } + + + auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); + + auto groups = controller::Group::listAll(); + std::map group_indices; + int count = 0; + for(auto it = groups.begin(); it != groups.end(); it++) { + group_indices.insert(std::pair((*it)->getModel()->getID(), count)); + count++; + } + + +%><%@ include file="header.cpsp" %> + <%= getErrorsHtml() %>

    Topic Admin Page

    -
    - +
    +
    +

    Ein neues Topic anlegen

    +
    +
    +
    + + + + + +
    + + + + "> + +
    <%@ include file="footer.cpsp" %> + + \ No newline at end of file From 155f3945000beb27c3b5e1a6869f0107ebc533ad Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 10 Sep 2020 11:11:37 +0200 Subject: [PATCH 074/195] fix compile error (missing }) --- src/cpp/controller/HederaTopic.cpp | 4 ++-- src/cpp/controller/HederaTopic.h | 1 + src/cpp/model/hedera/ConsensusCreateTopic.cpp | 4 +++- src/cpp/model/hedera/ConsensusCreateTopic.h | 5 +++-- src/cpp/model/hedera/TransactionBody.h | 4 +++- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp index 3885c31d8..31d18a94c 100644 --- a/src/cpp/controller/HederaTopic.cpp +++ b/src/cpp/controller/HederaTopic.cpp @@ -1,5 +1,5 @@ #include "HederaTopic.h" -#include "../model/hedera/Transaction.h" +//#include "../model/hedera/Transaction.h" namespace controller { HederaTopic::HederaTopic(model::table::HederaTopic* dbModel) @@ -21,6 +21,6 @@ namespace controller { Poco::UInt64 HederaTopic::hederaCreateTopic() { - + return 0; } } \ No newline at end of file diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h index de5552e39..4c2ebefb6 100644 --- a/src/cpp/controller/HederaTopic.h +++ b/src/cpp/controller/HederaTopic.h @@ -34,5 +34,6 @@ namespace controller { HederaTopic(model::table::HederaTopic* dbModel); }; +} #endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp index 6ca423102..a20985593 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.cpp +++ b/src/cpp/model/hedera/ConsensusCreateTopic.cpp @@ -1,3 +1,5 @@ + + #include "ConsensusCreateTopic.h" namespace model { @@ -42,4 +44,4 @@ namespace model { return false; } } -} \ No newline at end of file +} diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.h b/src/cpp/model/hedera/ConsensusCreateTopic.h index e61da46f3..b639ee305 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.h +++ b/src/cpp/model/hedera/ConsensusCreateTopic.h @@ -1,10 +1,10 @@ #ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H #define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H -#include "../../proto/hedera/ConsensusCreateTopic.pb.h" -#include "../../SingletonManager/MemoryManager.h" +#include "../../SingletonManager/MemoryManager.h" #include "../../controller/HederaId.h" +#include "../../proto/hedera/ConsensusCreateTopic.pb.h" namespace model { namespace hedera { @@ -28,4 +28,5 @@ namespace model { } } + #endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index ba421e014..7be8d2105 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -10,11 +10,13 @@ * */ -#include "../../proto/hedera/TransactionBody.pb.h" + #include "../../controller/NodeServer.h" #include "CryptoTransferTransaction.h" #include "ConsensusCreateTopic.h" +#include "../../proto/hedera/TransactionBody.pb.h" + namespace model { namespace hedera { class TransactionBody From 5862a61d59d8975d4fb2eeeb2214882a66d32aff Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 11 Sep 2020 12:29:06 +0200 Subject: [PATCH 075/195] change encryption state of crypto_keys --- skeema/gradido_login/crypto_keys.sql | 2 +- src/cpp/Crypto/KeyPairHedera.cpp | 1 + src/cpp/Crypto/KeyPairHedera.h | 3 + .../HTTPInterface/AdminHederaAccountPage.cpp | 139 ++++++++++++------ src/cpp/controller/CryptoKey.cpp | 30 ++++ src/cpp/controller/CryptoKey.h | 11 +- src/cpp/controller/HederaAccount.cpp | 62 ++++++-- src/cpp/controller/HederaAccount.h | 10 +- src/cpp/controller/HederaId.cpp | 10 ++ src/cpp/controller/HederaId.h | 2 + src/cpp/model/table/CryptoKey.cpp | 65 +++++++- src/cpp/model/table/CryptoKey.h | 9 ++ src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaId.cpp | 1 + src/cpp/model/table/ModelBase.cpp | 18 +++ src/cpp/model/table/ModelBase.h | 1 + src/cpsp/adminHederaAccount.cpsp | 101 +++++++++---- 17 files changed, 377 insertions(+), 89 deletions(-) diff --git a/skeema/gradido_login/crypto_keys.sql b/skeema/gradido_login/crypto_keys.sql index c79987755..1e5d6bad8 100644 --- a/skeema/gradido_login/crypto_keys.sql +++ b/skeema/gradido_login/crypto_keys.sql @@ -1,6 +1,6 @@ CREATE TABLE `crypto_keys` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `private_key` binary(80) NOT NULL, + `private_key` varbinary(80) NOT NULL, `public_key` binary(32) NOT NULL, `crypto_key_type_id` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`), diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index 62643cc99..e3a377864 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -184,6 +184,7 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr password) const; MemoryBin* getPrivateKeyCopy() const; + inline std::string getPrivateKeyHex(const Poco::AutoPtr password) const { if (!mPrivateKey) return "0x0"; return DataTypeConverter::binToHex(mPrivateKey); } protected: diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 54a416bef..3247e1130 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -51,40 +51,58 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); std::string action = ""; - std::string account_id_from_query; + Poco::AutoPtr query_hedera_account; + + // parsing get query params if(uri_query.size() >= 2) { if(uri_query[0].first == "action") { action = uri_query[0].second; } if(uri_query[1].first == "account_id") { + std::string account_id_from_query; + int account_id = 0; account_id_from_query = uri_query[1].second; - } - } - if(action == "updateBalance") { - int account_id = 0; - if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); - } else { - auto hedera_account = controller::HederaAccount::load("id", account_id); - if(!hedera_account.size() || hedera_account[0].isNull()) { - addError(new Error("Action Update Balance", "hedera id not found")); + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); } else { - hedera_time.reset(); - hedera_account[0]->hederaAccountGetBalance(user, this); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + auto hedera_accounts = controller::HederaAccount::load("id", account_id); + if(!hedera_accounts.size() || hedera_accounts[0].isNull()) { + addError(new Error("Action", "hedera account not found")); + } else { + query_hedera_account = hedera_accounts[0]; + } } } } - // add - else if(!form.empty()) { + // actions + if(!query_hedera_account.isNull()) + { + if(action == "updateBalance") + { + hedera_time.reset(); + query_hedera_account->hederaAccountGetBalance(user); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } + else if(action == "changeEncryption") + { + if(query_hedera_account->changeEncryption(user)) { + addNotification(new Success("Hedera Account", "success in changing encryption")); + } + } + } + else if(!form.empty()) // add + { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); auto numString = form.get("account-num", "0"); auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); auto publicKeyString = form.get("account-public-key", ""); auto networkTypeString = form.get("account-network-type", "0"); + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + int shardNum = 0; int realmNum = 0; int num = 0; @@ -144,7 +162,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user); + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); if(!crypto_key->getModel()->insertIntoDB(true)) { addError(new Error("DB Error", "Error saving crypto key in DB")); } @@ -152,15 +170,26 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request printf("crypto key found in db\n"); } if(0 == errorCount()) { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } } } @@ -169,7 +198,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request } } - + if(!query_hedera_account.isNull()) { + getErrors(query_hedera_account); + } // list accounts auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); @@ -231,7 +262,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -244,41 +275,63 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Hedera Id
    \t\t\t\n"; responseStream << "\t\t\t\t
    Balance
    \n"; responseStream << "\t\t\t\t
    Server Type
    \n"; + responseStream << "\t\t\t\t
    Verschlüsselt?
    \n"; responseStream << "\t\t\t\t
    Last Updated
    \n"; responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + std::string changeEncryption(""); + if(hedera_account_model->getUserId() == user->getModel()->getID()) { + changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); + } + //printf("change encryption: %s\n", changeEncryption.data()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + if(changeEncryption != "") { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + } responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -287,7 +340,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -296,26 +349,28 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; diff --git a/src/cpp/controller/CryptoKey.cpp b/src/cpp/controller/CryptoKey.cpp index aa8df1b8d..338ad05a4 100644 --- a/src/cpp/controller/CryptoKey.cpp +++ b/src/cpp/controller/CryptoKey.cpp @@ -113,8 +113,38 @@ namespace controller { return nullptr; } + return std::make_unique(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize()); } + bool CryptoKey::changeEncryption(Poco::AutoPtr user) + { + auto key_pair = getKeyPair(user); + if (!key_pair || !key_pair->hasPrivateKey()) { + addError(new Error("Crypto Key", "key pair or private key was null")); + return false; + } + auto model = getModel(); + auto mm = MemoryManager::getInstance(); + // update key type + model->changeKeyTypeToggleEncrypted(); + MemoryBin* private_key = nullptr; + if (model->isEncrypted()) { + private_key = key_pair->getCryptedPrivKey(user->getPassword()); + } + else { + private_key = key_pair->getPrivateKeyCopy(); + } + if (!private_key) { + addError(new Error("Crypto Key", " private_key not get")); + return false; + } + model->setPrivateKey(private_key); + // save changes into db + model->updatePrivkeyAndKeyType(); + + mm->releaseMemory(private_key); + return true; + } } diff --git a/src/cpp/controller/CryptoKey.h b/src/cpp/controller/CryptoKey.h index ef48c88f1..ddd2a7435 100644 --- a/src/cpp/controller/CryptoKey.h +++ b/src/cpp/controller/CryptoKey.h @@ -9,9 +9,15 @@ #include "TableControllerBase.h" #include "User.h" + + namespace controller { - class CryptoKey : public TableControllerBase + + class HederaAccount; + + class CryptoKey : public TableControllerBase, public NotificationList { + friend HederaAccount; public: ~CryptoKey(); @@ -31,8 +37,11 @@ namespace controller { std::unique_ptr getKeyPair(Poco::AutoPtr user) const; std::unique_ptr getKeyPair() const; + protected: + + bool changeEncryption(Poco::AutoPtr user); CryptoKey(model::table::CryptoKey* dbModel); }; diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index e4873ecf0..22a82c929 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -40,6 +40,20 @@ namespace controller { return resultVector; } + Poco::AutoPtr HederaAccount::load(Poco::AutoPtr hederaId) + { + if (!hederaId->isExistInDB()) return nullptr; + + auto db = new model::table::HederaAccount(); + auto result_count = db->loadFromDB("account_hedera_id", hederaId->getModel()->getID()); + if (1 == result_count) { + return new HederaAccount(db); + } + // maybe change later to using error manager and send email + printf("[HederaAccount::load] result_count not expected: %d\n", result_count); + return nullptr; + } + std::vector> HederaAccount::listAll() { auto db = new model::table::HederaAccount(); @@ -73,7 +87,13 @@ namespace controller { return resultVector; } - bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) + Poco::AutoPtr HederaAccount::getCryptoKey() const + { + auto model = getModel(); + return controller::CryptoKey::load(model->getCryptoKeyId()); + } + + bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr user) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -86,13 +106,13 @@ namespace controller { auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); if (crypto_key.isNull()) { - if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));} - else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); } + addError(new Error("Keys", "could not found crypto key for account")); + printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); return false; } auto hedera_key_pair = crypto_key->getKeyPair(user); if (!hedera_key_pair) { - if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));} + addError(new Error("Keys", "error decrypting private key")); printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); return false; } @@ -111,13 +131,8 @@ namespace controller { account_model->updateIntoDB("balance", response.getAccountBalance()); } else { - if (errorReceiver) { - errorReceiver->addError(new Error("Hedera", "Hedera request failed")); - errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); - } - else { - printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data()); - } + addError(new Error("Hedera", "Hedera request failed")); + addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); } //request.requestViaPHPRelay(query); } @@ -125,13 +140,32 @@ namespace controller { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } - if (errorReceiver) { - errorReceiver->getErrors(&request); - } + getErrors(&request); return false; } + bool HederaAccount::changeEncryption(Poco::AutoPtr user) + { + assert(!user.isNull() && user->getModel()); + auto model = getModel(); + assert(!model.isNull()); + + if (user->getModel()->getID() != model->getUserId()) { + addError(new Error("Hedera Account", "wrong user")); + return false; + } + auto crypto_key = controller::CryptoKey::load(model->getCryptoKeyId()); + if (crypto_key.isNull()) { + addError(new Error("Hedera Account", "couldn't find crypto key")); + return false; + } + bool result = crypto_key->changeEncryption(user); + getErrors(crypto_key); + return result; + + } + std::string HederaAccount::toShortSelectOptionName() { diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index a9a53d528..77f34aa87 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -8,9 +8,10 @@ #include "Poco/SharedPtr.h" #include "TableControllerBase.h" +#include "CryptoKey.h" namespace controller { - class HederaAccount : public TableControllerBase + class HederaAccount : public TableControllerBase, public NotificationList { public: ~HederaAccount(); @@ -18,6 +19,7 @@ namespace controller { static Poco::AutoPtr create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET); static std::vector> load(const std::string& fieldName, int fieldValue); + static Poco::AutoPtr load(Poco::AutoPtr hederaId); static std::vector> listAll(); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } @@ -25,11 +27,15 @@ namespace controller { std::string HederaAccount::toShortSelectOptionName(); inline Poco::AutoPtr getModel() { return _getModel(); } + inline const model::table::HederaAccount* getModel() const { return _getModel(); } inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool hederaAccountGetBalance(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); + Poco::AutoPtr getCryptoKey() const; + + bool hederaAccountGetBalance(Poco::AutoPtr user); + bool changeEncryption(Poco::AutoPtr user); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index ce171a7a8..de2cf1dfa 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -37,4 +37,14 @@ namespace controller { protoAccountId->set_realmnum(model->getRealmNum()); protoAccountId->set_accountnum(model->getNum()); } + + bool HederaId::isExistInDB() + { + auto model = getModel(); + if (model->getID() > 0) return true; + //std::vector loadFromDB(const std::vector& fieldNames, const std::vector& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0); + model->isExistInDB(); + return model->getID() != 0; + + } } \ No newline at end of file diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index ae9296a43..1cf967927 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -20,6 +20,8 @@ namespace controller { static Poco::AutoPtr load(int id); + bool isExistInDB(); + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/model/table/CryptoKey.cpp b/src/cpp/model/table/CryptoKey.cpp index a4f1034e3..f461edc02 100644 --- a/src/cpp/model/table/CryptoKey.cpp +++ b/src/cpp/model/table/CryptoKey.cpp @@ -1,5 +1,5 @@ #include "CryptoKey.h" -#include "../../lib/DataTypeConverter.h" + using namespace Poco::Data::Keywords; namespace model { @@ -51,6 +51,8 @@ namespace model { return ""; } + + bool CryptoKey::hasPrivateKeyEncrypted() const { const KeyType type = (KeyType)(mKeyType); @@ -70,6 +72,39 @@ namespace model { return false; } + void CryptoKey::setPrivateKey(const MemoryBin* privateKey) + { + if (!privateKey) { + mPrivateKey = Poco::Nullable(); + } + else { + mPrivateKey = Poco::Nullable(Poco::Data::BLOB(*privateKey, privateKey->size())); + } + + } + + bool CryptoKey::changeKeyTypeToggleEncrypted() + { + const KeyType type = (KeyType)(mKeyType); + if (type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) { + mKeyType = KEY_TYPE_ED25519_SODIUM_CLEAR; + return true; + } + if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED) { + mKeyType = KEY_TYPE_ED25519_HEDERA_CLEAR; + return true; + } + if (type == KEY_TYPE_ED25519_SODIUM_CLEAR) { + mKeyType = KEY_TYPE_ED25519_SODIUM_ENCRYPTED; + return true; + } + if (type == KEY_TYPE_ED25519_HEDERA_CLEAR) { + mKeyType = KEY_TYPE_ED25519_HEDERA_ENCRYPTED; + return true; + } + return false; + } + Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); @@ -103,5 +138,33 @@ namespace model { unlock(); return insert; } + + size_t CryptoKey::updatePrivkeyAndKeyType() + { + Poco::ScopedLock _lock(mWorkMutex); + if (mPrivateKey.isNull() || !mID) { + return 0; + } + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement update(session); + + update << "UPDATE " << getTableName() << " SET private_key = ?, crypto_key_type_id = ? where id = ?;", + use(mPrivateKey), use(mKeyType), use(mID); + + + size_t resultCount = 0; + try { + return update.execute(); + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "[updatePrivkeyAndKeyType] mysql error by update", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: \n", toString().data())); + } + //printf("data valid: %s\n", toString().data()); + return 0; + } + } } \ No newline at end of file diff --git a/src/cpp/model/table/CryptoKey.h b/src/cpp/model/table/CryptoKey.h index c1fa0b66d..0dcbb618f 100644 --- a/src/cpp/model/table/CryptoKey.h +++ b/src/cpp/model/table/CryptoKey.h @@ -3,6 +3,7 @@ #include "ModelBase.h" #include "Poco/Types.h" +#include "../../lib/DataTypeConverter.h" namespace model { namespace table { @@ -27,13 +28,21 @@ namespace model { std::string toString(); inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + inline std::string getPublicKeyHexString() const { return DataTypeConverter::binToHex(mPublicKey); }; size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } bool hasPrivateKeyEncrypted() const; bool isEncrypted() const; + bool changeKeyTypeToggleEncrypted(); inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); } inline const std::vector& getPrivateKey() const { return mPrivateKey.value().content(); } + size_t updatePrivkeyAndKeyType(); + + //! \brief set encrypted private key + //! \param privateKey copy data, didn't move memory bin + void setPrivateKey(const MemoryBin* privateKey); + static const char* typeToString(KeyType type); protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); diff --git a/src/cpp/model/table/HederaAccount.h b/src/cpp/model/table/HederaAccount.h index 6b0d636a0..699330adf 100644 --- a/src/cpp/model/table/HederaAccount.h +++ b/src/cpp/model/table/HederaAccount.h @@ -35,6 +35,7 @@ namespace model { inline int getAccountHederaId() const { return mAccountHederaId; } inline int getCryptoKeyId() const { return mAccountKeyId; } + inline int getUserId() const { return mUserId; } inline Poco::UInt64 getBalance() { return mBalance; } inline double getBalanceDouble() { return (double)mBalance / 100000000.0; } diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index 9f26f05c5..d6ceb8cb7 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -55,6 +55,7 @@ namespace model { return mID; } + Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { diff --git a/src/cpp/model/table/ModelBase.cpp b/src/cpp/model/table/ModelBase.cpp index 7bb7301f6..49b470d7a 100644 --- a/src/cpp/model/table/ModelBase.cpp +++ b/src/cpp/model/table/ModelBase.cpp @@ -78,6 +78,24 @@ namespace model { return false; } + bool ModelBase::isExistInDB() + { + auto cm = ConnectionManager::getInstance(); + Poco::ScopedLock _lock(mWorkMutex); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement select = _loadIdFromDB(session); + try { + select.executeAsync(); + return select.wait() == 1; + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "mysql error by select id, check if exist in db", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: ", toString().data())); + } + return false; + } + bool ModelBase::deleteFromDB() { Poco::ScopedLock _lock(mWorkMutex); diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 62ff4958a..55ae0962a 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -40,6 +40,7 @@ namespace model { size_t loadFromDB(const std::string& fieldName, const T& fieldValue); template bool isExistInDB(const std::string& fieldName, const T& fieldValue); + bool isExistInDB(); template std::vector loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0); template diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 95d6992b7..b55701b1b 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -30,40 +30,58 @@ Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); std::string action = ""; - std::string account_id_from_query; + Poco::AutoPtr query_hedera_account; + + // parsing get query params if(uri_query.size() >= 2) { if(uri_query[0].first == "action") { action = uri_query[0].second; } if(uri_query[1].first == "account_id") { + std::string account_id_from_query; + int account_id = 0; account_id_from_query = uri_query[1].second; - } - } - if(action == "updateBalance") { - int account_id = 0; - if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); - } else { - auto hedera_account = controller::HederaAccount::load("id", account_id); - if(!hedera_account.size() || hedera_account[0].isNull()) { - addError(new Error("Action Update Balance", "hedera id not found")); + if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting account_id_from_query to int")); } else { - hedera_time.reset(); - hedera_account[0]->hederaAccountGetBalance(user, this); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + auto hedera_accounts = controller::HederaAccount::load("id", account_id); + if(!hedera_accounts.size() || hedera_accounts[0].isNull()) { + addError(new Error("Action", "hedera account not found")); + } else { + query_hedera_account = hedera_accounts[0]; + } } } } - // add - else if(!form.empty()) { + // actions + if(!query_hedera_account.isNull()) + { + if(action == "updateBalance") + { + hedera_time.reset(); + query_hedera_account->hederaAccountGetBalance(user); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } + else if(action == "changeEncryption") + { + if(query_hedera_account->changeEncryption(user)) { + addNotification(new Success("Hedera Account", "success in changing encryption")); + } + } + } + else if(!form.empty()) // add + { // collect auto shardNumString = form.get("account-shard-num", "0"); auto realmNumString = form.get("account-realm-num", "0"); auto numString = form.get("account-num", "0"); auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); auto publicKeyString = form.get("account-public-key", ""); auto networkTypeString = form.get("account-network-type", "0"); + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + int shardNum = 0; int realmNum = 0; int num = 0; @@ -123,7 +141,7 @@ auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user); + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); if(!crypto_key->getModel()->insertIntoDB(true)) { addError(new Error("DB Error", "Error saving crypto key in DB")); } @@ -131,15 +149,26 @@ printf("crypto key found in db\n"); } if(0 == errorCount()) { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } } } @@ -148,7 +177,9 @@ } } - + if(!query_hedera_account.isNull()) { + getErrors(query_hedera_account); + } // list accounts auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); @@ -165,21 +196,33 @@
    Hedera Id
    Balance
    Server Type
    +
    Verschlüsselt?
    Last Updated
    Aktionen
    <% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); + std::string changeEncryption(""); + if(hedera_account_model->getUserId() == user->getModel()->getID()) { + changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); + } + //printf("change encryption: %s\n", changeEncryption.data()); %>
    <%= (*it)->getHederaId()->getModel()->toString() %>
    <%= hedera_account_model->getBalanceDouble() %> hbar
    <%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
    +
    <%= (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" %>
    <%= hedera_account_model->getUpdatedString() %>
    - + <% if(changeEncryption != "") { %> + + <% } %>
    <% } %>
    @@ -195,6 +238,8 @@ + + From 995c6932527a34041117c71ee7bc20f13feb1330 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 14 Sep 2020 21:09:18 +0200 Subject: [PATCH 076/195] Update code for sending transaction over hedera --- src/cpp/Crypto/KeyPairHedera.cpp | 18 + src/cpp/Crypto/KeyPairHedera.h | 7 +- .../HTTPInterface/AdminHederaAccountPage.cpp | 364 +++++++---- .../SingletonManager/HederaTaskManager.cpp | 17 + src/cpp/SingletonManager/HederaTaskManager.h | 23 + src/cpp/SingletonManager/SessionManager.cpp | 1 + src/cpp/SingletonManager/SessionManager.h | 1 + src/cpp/controller/HederaAccount.cpp | 75 ++- src/cpp/controller/HederaAccount.h | 9 + src/cpp/controller/HederaId.cpp | 47 ++ src/cpp/controller/HederaId.h | 6 + src/cpp/controller/HederaRequest.cpp | 28 + src/cpp/controller/HederaRequest.h | 7 + src/cpp/controller/HederaTopic.cpp | 2 + src/cpp/controller/HederaTopic.h | 4 +- src/cpp/lib/DataTypeConverter.cpp | 28 + src/cpp/lib/DataTypeConverter.h | 1 + .../model/hedera/ConsensusSubmitMessage.cpp | 42 ++ src/cpp/model/hedera/ConsensusSubmitMessage.h | 32 + .../model/hedera/CryptoCreateTransaction.cpp | 22 +- .../model/hedera/CryptoCreateTransaction.h | 10 +- .../hedera/CryptoTransferTransaction.cpp | 5 - .../model/hedera/CryptoTransferTransaction.h | 2 +- src/cpp/model/hedera/Transaction.cpp | 29 + src/cpp/model/hedera/Transaction.h | 3 + src/cpp/model/hedera/TransactionBody.cpp | 46 +- src/cpp/model/hedera/TransactionBody.h | 16 + src/cpp/model/hedera/TransactionResponse.cpp | 18 + src/cpp/model/hedera/TransactionResponse.h | 30 + src/cpp/model/table/HederaId.cpp | 7 + src/cpp/model/table/HederaId.h | 4 +- src/cpp/tasks/HederaTask.cpp | 0 src/cpp/tasks/HederaTask.h | 15 + src/cpp/tasks/SigningTransaction.cpp | 595 ++++++++++-------- src/cpsp/adminHederaAccount.cpsp | 291 ++++++--- 35 files changed, 1286 insertions(+), 519 deletions(-) create mode 100644 src/cpp/SingletonManager/HederaTaskManager.cpp create mode 100644 src/cpp/SingletonManager/HederaTaskManager.h create mode 100644 src/cpp/model/hedera/TransactionResponse.cpp create mode 100644 src/cpp/model/hedera/TransactionResponse.h create mode 100644 src/cpp/tasks/HederaTask.cpp create mode 100644 src/cpp/tasks/HederaTask.h diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index e3a377864..c2738e886 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -96,6 +96,24 @@ KeyPairHedera::~KeyPairHedera() } } +KeyPairHedera* KeyPairHedera::create() +{ + /* + The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) + and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + + assert(getPublicKeySize() == crypto_sign_PUBLICKEYBYTES); + + auto mm = MemoryManager::getInstance(); + auto private_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES); + auto public_key = mm->getFreeMemory(getPublicKeySize()); + + crypto_sign_keypair(*public_key, *private_key); + return new KeyPairHedera(private_key, public_key); +} + void KeyPairHedera::createKeyFromSeed(const unsigned char* seed, size_t seedSize) { diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 4613618c5..769f29af6 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -26,6 +26,9 @@ public: KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr); KeyPairHedera(const std::vector& privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0); + + + static KeyPairHedera* create(); ~KeyPairHedera(); @@ -43,12 +46,12 @@ public: const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;} inline bool isTheSame(const KeyPairHedera& b) const { - return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE); + return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, getPublicKeySize()); } inline bool isTheSame(const unsigned char* pubkey) const { if (!pubkey) return false; - return 0 == sodium_memcmp(mPublicKey, pubkey, ed25519_pubkey_SIZE); + return 0 == sodium_memcmp(mPublicKey, pubkey, getPublicKeySize()); } //! \return 0 if the same //! \return -1 if not the same diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 3247e1130..5ff4f7218 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -45,6 +45,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + int auto_renew_period = 604800; // 7 Tage + int auto_renew_account = 0; + double initial_balance = 0.0; Profiler hedera_time; std::string hedera_time_string; @@ -80,8 +83,11 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(action == "updateBalance") { hedera_time.reset(); - query_hedera_account->hederaAccountGetBalance(user); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + if(query_hedera_account->hederaAccountGetBalance(user)) { + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } else { + addError(new ParamError("Hedera", "crypto get balance failed in ", hedera_time.string())); + } } else if(action == "changeEncryption") { @@ -90,113 +96,150 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request } } } - else if(!form.empty()) // add + else if(!form.empty()) // add or create { - // collect - auto shardNumString = form.get("account-shard-num", "0"); - auto realmNumString = form.get("account-realm-num", "0"); - auto numString = form.get("account-num", "0"); - auto privateKeyString = form.get("account-private-key", ""); - auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); - auto publicKeyString = form.get("account-public-key", ""); - auto networkTypeString = form.get("account-network-type", "0"); + auto creationButton = form.get("create",""); + if(creationButton != "") { - //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); - - int shardNum = 0; - int realmNum = 0; - int num = 0; - int networkType = 0; - - MemoryBin* private_key = nullptr; - MemoryBin* public_key = nullptr; - - // validate - if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "shard num not integer")); - } else { - if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting shardNumString to int")); - } - } - if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "realm num not integer")); - } else { - if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting realmNumString to int")); - } - } - if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "num not integer")); - } else { - if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting num to int")); - } - } - if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "private key not hex")); - } - if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "public key not hex")); - } - if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Network Type", "not integer")); - } else { - if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting network type to int")); - } - if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { - addError(new Error("Network Type", "invalid value")); - } - } - - if(0 == errorCount()) { - - auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + // collect + auto auto_renew_account_string = form.get("account-auto-renew-account", "0"); + auto auto_renew_period_string = form.get("account-auto-renew-period", "604800"); + auto account_initial_balance_string = form.get("account-initial-balance", "0"); - private_key = DataTypeConverter::hexToBin(privateKeyString); - public_key = DataTypeConverter::hexToBin(publicKeyString); - - - KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); - - if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); - if(!crypto_key->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving crypto key in DB")); - } + if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew account id not an integer")); } else { - printf("crypto key found in db\n"); - } - if(0 == errorCount()) { - - if(hedera_id->isExistInDB()) { - auto hedera_account = controller::HederaAccount::load(hedera_id); - if(hedera_account.isNull()) { - addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); - } else { - addError(new Error("Hedera Account", "Account already exist (same account id")); - } - - } else { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); - } + if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew account id to int")); } } - mm->releaseMemory(private_key); - mm->releaseMemory(public_key); - } + if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew period not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew period to int")); + } + } + + if(!sm->isValid(account_initial_balance_string, VALIDATE_ONLY_DECIMAL)) { + addError(new Error("Account", "initial balance not an decimal")); + } else { + if(DataTypeConverter::strToDouble(account_initial_balance_string, initial_balance) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Double convert error", "Error converting initial balance to double")); + } + } + if(0 == errorCount()) + { + } + + } else { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); + } + if(0 == errorCount()) { + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); + } + } } if(!query_hedera_account.isNull()) { getErrors(query_hedera_account); @@ -262,7 +305,15 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
    "; // end include header_large.cpsp responseStream << "\n"; -#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << "\n"; +#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -280,7 +331,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); @@ -288,59 +339,63 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(hedera_account_model->getUserId() == user->getModel()->getID()) { changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); } + auto isEncrypted = (*it)->getCryptoKey()->getModel()->isEncrypted(); //printf("change encryption: %s\n", changeEncryption.data()); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 266 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    "; -#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - responseStream << ( (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" ); + responseStream << "\t\t\t\t\t
    "; +#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << ( isEncrypted ? "Ja": "Nein" ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" if(changeEncryption != "") { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 279 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; - responseStream << "\t

    Einen neuen Account anlegen

    \n"; + responseStream << "\t

    Ein existierenden Account eintragen

    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -356,25 +411,75 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t

    Ein neuen Account anlegen

    \n"; + responseStream << "\t\t

    Bei Hedera einen neuen Account anlegen und zum Start Hashbars von einem existierenden Account überweisen.

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t
    \n"; responseStream << "
    \n"; // begin include footer.cpsp responseStream << "
    \n"; @@ -400,5 +505,18 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << ""; // end include footer.cpsp responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; if (_compressResponse) _gzipStream.close(); } diff --git a/src/cpp/SingletonManager/HederaTaskManager.cpp b/src/cpp/SingletonManager/HederaTaskManager.cpp new file mode 100644 index 000000000..f54ca58f3 --- /dev/null +++ b/src/cpp/SingletonManager/HederaTaskManager.cpp @@ -0,0 +1,17 @@ +#include "HederaTaskManager.h" + +HederaTaskManager* HederaTaskManager::getInstance() +{ + static HederaTaskManager one; + return &one; +} + +HederaTaskManager::HederaTaskManager() +{ + +} + +HederaTaskManager::~HederaTaskManager() +{ + +} \ No newline at end of file diff --git a/src/cpp/SingletonManager/HederaTaskManager.h b/src/cpp/SingletonManager/HederaTaskManager.h new file mode 100644 index 000000000..361ace551 --- /dev/null +++ b/src/cpp/SingletonManager/HederaTaskManager.h @@ -0,0 +1,23 @@ +#ifndef __GRADIDO_LOGIN_SINGLETON_MANAGER_HEDERA_TASK_MANAGER_H +#define __GRADIDO_LOGIN_SINGLETON_MANAGER_HEDERA_TASK_MANAGER_H + +/*! + * @author: Dario Rekowski + * + * @date: 11.09.2020 + * + * @brief: Manage Hedera Task, waiting on Consensus for Hedera Transactions + * +*/ + +class HederaTaskManager +{ +public: + ~HederaTaskManager(); + + static HederaTaskManager* getInstance(); +protected: + HederaTaskManager(); +}; + +#endif //__GRADIDO_LOGIN_SINGLETON_MANAGER_HEDERA_TASK_MANAGER_H \ No newline at end of file diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 1eb9c436c..5e5d42264 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -49,6 +49,7 @@ bool SessionManager::init() case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; + case VALIDATE_ONLY_DECIMAL: mValidations[i] = new Poco::RegularExpression("^[0-9]*(\.|,)[0-9]*$"); break; case VALIDATE_ONLY_HEX: mValidations[i] = new Poco::RegularExpression("^(0x)?[a-fA-F0-9]*$"); break; //case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}$"); break; case VALIDATE_ONLY_URL: mValidations[i] = new Poco::RegularExpression("^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\/?"); break; diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index 9b83c712d..1463e6502 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -29,6 +29,7 @@ enum SessionValidationTypes { VALIDATE_PASSPHRASE, VALIDATE_HAS_NUMBER, VALIDATE_ONLY_INTEGER, + VALIDATE_ONLY_DECIMAL, VALIDATE_ONLY_HEX, VALIDATE_ONLY_URL, VALIDATE_HAS_SPECIAL_CHARACTER, diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 22a82c929..25f3c7245 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -3,8 +3,13 @@ #include "NodeServer.h" #include "CryptoKey.h" #include "../model/hedera/Query.h" +//#include "../model/hedera/Tr" #include "HederaRequest.h" +#include "../SingletonManager/ErrorManager.h" + +using namespace Poco::Data::Keywords; + namespace controller { HederaAccount::HederaAccount(model::table::HederaAccount* dbModel) @@ -54,6 +59,51 @@ namespace controller { return nullptr; } + Poco::AutoPtr HederaAccount::pick(model::table::HederaNetworkType networkType, bool encrypted/* = false*/) + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement select(session); + + Poco::Tuple result_tuple; + int crypto_key_type = encrypted ? model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED : model::table::KEY_TYPE_ED25519_HEDERA_CLEAR; + //id, user_id, account_hedera_id, account_key_id, balance, network_type, updated + + select << "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num FROM hedera_accounts as account " + << "JOIN hedera_ids as i ON(i.id = account.account_hedera_id) " + << "JOIN crypto_keys as k ON(k.id = account.account_key_id) " + << "WHERE account.network_type = ? AND k.crypto_key_type_id = ? ORDER BY RAND() LIMIT 1 ", + into(result_tuple), use(networkType), use(crypto_key_type); + + try { + select.executeAsync(); + select.wait(); + if (1 == select.rowsExtracted()) { + auto db = new model::table::HederaAccount( + result_tuple.get<1>(), result_tuple.get<2>(), result_tuple.get<3>(), + result_tuple.get<4>(), networkType + ); + db->setID(result_tuple.get<0>()); + Poco::AutoPtr hedera_account(new HederaAccount(db)); + auto hedera_id_db = new model::table::HederaId(result_tuple.get<5>(), result_tuple.get<6>(), result_tuple.get<7>()); + Poco::AutoPtr hedera_id(new HederaId(hedera_id_db)); + hedera_account->setHederaId(hedera_id); + return hedera_account; + } + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + static const char* function_name = "HederaAccount::pick"; + em->addError(new ParamError(function_name, "mysql error: ", ex.displayText())); + em->addError(new ParamError(function_name, "network type: ", networkType)); + em->addError(new ParamError(function_name, "encrypted: ", (int)encrypted)); + em->sendErrorsAsEmail(); + } + + return nullptr; + + } + std::vector> HederaAccount::listAll() { auto db = new model::table::HederaAccount(); @@ -140,11 +190,27 @@ namespace controller { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } - getErrors(&request); + if (0 == errorCount() && 0 == request.errorCount()) { + return true; + } + getErrors(&request); return false; } + bool HederaAccount::hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance) + { + auto account_model = getModel(); + auto new_key_pair = KeyPairHedera::create(); + auto transaction_body = createTransactionBody(); + //CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod); + model::hedera::CryptoCreateTransaction create_transaction(new_key_pair->getPublicKey(), initialBalance, autoRenewPeriodSeconds); + transaction_body->setCryptoCreate(create_transaction); + + + return false; + } + bool HederaAccount::changeEncryption(Poco::AutoPtr user) { assert(!user.isNull() && user->getModel()); @@ -166,6 +232,13 @@ namespace controller { } + std::unique_ptr HederaAccount::createTransactionBody() + { + auto account_model = getModel(); + auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); + return std::make_unique(mHederaID, hedera_node); + } + std::string HederaAccount::toShortSelectOptionName() { diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 77f34aa87..882800713 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -5,6 +5,8 @@ #include "User.h" #include "../model/table/HederaAccount.h" +#include "../model/hedera/TransactionBody.h" + #include "Poco/SharedPtr.h" #include "TableControllerBase.h" @@ -21,6 +23,8 @@ namespace controller { static std::vector> load(const std::string& fieldName, int fieldValue); static Poco::AutoPtr load(Poco::AutoPtr hederaId); static std::vector> listAll(); + //! \brief for picking a account for paying transaction, mostly consensusSendMessage + static Poco::AutoPtr pick(model::table::HederaNetworkType networkType, bool encrypted = false); inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } @@ -35,9 +39,14 @@ namespace controller { Poco::AutoPtr getCryptoKey() const; bool hederaAccountGetBalance(Poco::AutoPtr user); + bool hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance); bool changeEncryption(Poco::AutoPtr user); + //! \brief create Transaction body with this hedera account as operator + std::unique_ptr createTransactionBody(); + protected: + HederaAccount(model::table::HederaAccount* dbModel); Poco::AutoPtr mHederaID; diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index de2cf1dfa..3b9627c8b 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -1,4 +1,7 @@ #include "HederaId.h" +#include "../SingletonManager/ErrorManager.h" + +using namespace Poco::Data::Keywords; namespace controller { @@ -30,6 +33,42 @@ namespace controller { return nullptr; } + Poco::AutoPtr HederaId::find(int groupId, model::table::HederaNetworkType networkType) + { + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + model::table::HederaIdTuple result_tuple; + + Poco::Data::Statement select(session); + select << "SELECT h.id, h.shardNum, h.realmNum, h.num FROM hedera_ids as h " + << "JOIN hedera_topics as topic ON(topic.topic_hedera_id = h.id) " + << "JOIN hedera_accounts as account ON(account.id = topic.auto_renew_account_hedera_id) " + << "WHERE topic.group_id = ? AND account.network_type = ?" + , into(result_tuple), use(groupId), use(networkType); + + try { + /*select.executeAsync(); + select.wait(); + auto result_count = select.rowsExtracted();*/ + auto result_count = select.execute(); + if (1 == result_count) { + return new HederaId(new model::table::HederaId(result_tuple)); + } + else { + printf("[HederaId::find] result_count other as expected: %d\n", result_count); + } + } + catch (Poco::Exception& ex) { + auto em = ErrorManager::getInstance(); + static const char* function_name = "HederaId::find"; + em->addError(new ParamError(function_name, "mysql error: ", ex.displayText())); + em->addError(new ParamError(function_name, "group id: ", groupId)); + em->addError(new ParamError(function_name, "network type: ", (int)networkType)); + em->sendErrorsAsEmail(); + } + return nullptr; + } + void HederaId::copyToProtoAccountId(proto::AccountID* protoAccountId) const { auto model = getModel(); @@ -38,6 +77,14 @@ namespace controller { protoAccountId->set_accountnum(model->getNum()); } + void HederaId::copyToProtoTopicId(proto::TopicID* protoTopicId) const + { + auto model = getModel(); + protoTopicId->set_shardnum(model->getShardNum()); + protoTopicId->set_realmnum(model->getRealmNum()); + protoTopicId->set_topicnum(model->getNum()); + } + bool HederaId::isExistInDB() { auto model = getModel(); diff --git a/src/cpp/controller/HederaId.h b/src/cpp/controller/HederaId.h index 1cf967927..0bfc1f691 100644 --- a/src/cpp/controller/HederaId.h +++ b/src/cpp/controller/HederaId.h @@ -2,6 +2,7 @@ #define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE #include "../model/table/HederaId.h" +#include "../model/table/HederaAccount.h" #include "Poco/SharedPtr.h" @@ -10,8 +11,10 @@ #include "../proto/hedera/BasicTypes.pb.h" namespace controller { + class HederaAccount; class HederaId : public TableControllerBase { + friend HederaAccount; public: ~HederaId(); @@ -19,6 +22,8 @@ namespace controller { static Poco::AutoPtr create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); static Poco::AutoPtr load(int id); + //! \return hedera topic id for group and network type (should exist only one) + static Poco::AutoPtr find(int groupId, model::table::HederaNetworkType networkType); bool isExistInDB(); @@ -28,6 +33,7 @@ namespace controller { inline const model::table::HederaId* getModel() const { return _getModel(); } void copyToProtoAccountId(proto::AccountID* protoAccountId) const; + void copyToProtoTopicId(proto::TopicID* protoTopicId) const; protected: diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 64998fa6a..7ddb95800 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -1,5 +1,6 @@ #include "HederaRequest.h" #include "../proto/hedera/CryptoService.grpc.pb.h" +#include "../proto/hedera/ConsensusService.grpc.pb.h" #include "../lib/DataTypeConverter.h" @@ -71,6 +72,33 @@ HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transacti return HEDERA_REQUEST_RETURN_OK; } +HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, HederaTask* task) +{ + assert(transaction && task); + auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials()); + + grpc::ClientContext context; + std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + + std::chrono::milliseconds(5000); + context.set_deadline(deadline); + auto transaction_type = transaction->getType(); + if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type) { + auto stub = proto::ConsensusService::NewStub(channel); + + auto status = stub->submitMessage(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse()); + if (status.ok()) { + return HEDERA_REQUEST_RETURN_OK; + } + else { + addError(new ParamError("Hedera Request", "consensus service submit message error message:", status.error_message())); + addError(new ParamError("Hedera Request", "details: ", status.error_details())); + return HEDERA_REQUEST_RETURN_ERROR; + } + } + addError(new ParamError("Hedera Request", "not implemnetet or unknown transaction type", transaction_type)); + return HEDERA_REQUEST_UNKNOWN_TRANSACTION; +} + #include "Poco/JSON/Object.h" #include "../lib/JsonRequest.h" diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 34bd304a1..56adf3c79 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -14,12 +14,16 @@ #include "../model/hedera/Query.h" #include "../model/hedera/Transaction.h" #include "../model/hedera/Response.h" +#include "../model/hedera/TransactionResponse.h" +#include "../tasks/HederaTask.h" enum HederaRequestReturn { HEDERA_REQUEST_RETURN_OK, HEDERA_REQUEST_RETURN_PARSE_ERROR, HEDERA_REQUEST_RETURN_ERROR, + HEDERA_REQUEST_UNKNOWN_TRANSACTION, + HEDERA_REQUEST_UNKNOWN_QUERY, HEDERA_REQUEST_CONNECT_ERROR }; @@ -32,6 +36,9 @@ public: HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response); + //! + //! \param task goes into HederaTaskManager and will be run after transaction + HederaRequestReturn request(model::hedera::Transaction* transaction, HederaTask* task); //! for testing, didn't work server say invalid json :/ HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp index 31d18a94c..d852b57e7 100644 --- a/src/cpp/controller/HederaTopic.cpp +++ b/src/cpp/controller/HederaTopic.cpp @@ -19,6 +19,8 @@ namespace controller { return Poco::AutoPtr(hedera_topic); } + + Poco::UInt64 HederaTopic::hederaCreateTopic() { return 0; diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h index 4c2ebefb6..c7b169b4b 100644 --- a/src/cpp/controller/HederaTopic.h +++ b/src/cpp/controller/HederaTopic.h @@ -13,6 +13,7 @@ #include "TableControllerBase.h" #include "../model/table/HederaTopic.h" + namespace controller { class HederaTopic : public TableControllerBase { @@ -27,6 +28,7 @@ namespace controller { inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + inline Poco::AutoPtr getModel() { return _getModel(); } @@ -36,4 +38,4 @@ namespace controller { }; } -#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H \ No newline at end of file +#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index 72e6aceb8..0e84b4be4 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -55,6 +55,34 @@ namespace DataTypeConverter } } + NumberParseState strToDouble(const std::string& input, double& result) + { + auto comma_position = input.find(','); + std::string input_filtered = input; + if (comma_position > 0 && comma_position != input.npos) { + input_filtered = input_filtered.replace(comma_position, 0, 1, '.'); + } + try { + result = stod(input_filtered); + return NUMBER_PARSE_OKAY; + } + catch (const std::invalid_argument& ia) + { + printf("[strToDouble] exception: invalid argument: %s\n", ia.what()); + return NUMBER_PARSE_INVALID_ARGUMENT; + } + catch (const std::out_of_range& oor) + { + printf("[strToDouble] exception: out or range: %s\n", oor.what()); + return NUMBER_PARSE_OUT_OF_RANGE; + } + catch (const std::logic_error & ler) + { + printf("[strToDouble] exception: logical error: %s\n", ler.what()); + return NUMBER_PARSE_LOGIC_ERROR; + } + } + const char* numberParseStateToString(NumberParseState state) { switch (state) { diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index d970d697d..933fdfb74 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -23,6 +23,7 @@ namespace DataTypeConverter { NumberParseState strToInt(const std::string& input, int& result); NumberParseState strToInt(const std::string& input, unsigned long long& result); + NumberParseState strToDouble(const std::string& input, double& result); MemoryBin* hexToBin(const std::string& hexString); MemoryBin* base64ToBin(const std::string& base64String); diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.cpp b/src/cpp/model/hedera/ConsensusSubmitMessage.cpp index e69de29bb..18da97c73 100644 --- a/src/cpp/model/hedera/ConsensusSubmitMessage.cpp +++ b/src/cpp/model/hedera/ConsensusSubmitMessage.cpp @@ -0,0 +1,42 @@ +#include "ConsensusSubmitMessage.h" + +namespace model { + namespace hedera { + ConsensusSubmitMessage::ConsensusSubmitMessage(Poco::AutoPtr topicID) + : mConsensusMessageBody(nullptr) + { + mConsensusMessageBody = new proto::ConsensusSubmitMessageTransactionBody; + topicID->copyToProtoTopicId(mConsensusMessageBody->mutable_topicid()); + } + + ConsensusSubmitMessage::~ConsensusSubmitMessage() + { + if (mConsensusMessageBody) { + delete mConsensusMessageBody; + mConsensusMessageBody = nullptr; + } + } + + bool ConsensusSubmitMessage::validate() + { + // TODO: unpack gradido transaction and make simple validation check + assert(mConsensusMessageBody); + if (0 == mConsensusMessageBody->message().size()) { + printf("[ConsensusSubmitMessage::validate] empty message\n"); + return false; + } + if (!mConsensusMessageBody->has_topicid()) { + printf("[ConsensusSubmitMessage::validate] empty topic id\n"); + return false; + } + + return true; + } + + void ConsensusSubmitMessage::setMessage(std::string byteString) + { + assert(mConsensusMessageBody); + mConsensusMessageBody->set_message(byteString); + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusSubmitMessage.h b/src/cpp/model/hedera/ConsensusSubmitMessage.h index e69de29bb..d08b72279 100644 --- a/src/cpp/model/hedera/ConsensusSubmitMessage.h +++ b/src/cpp/model/hedera/ConsensusSubmitMessage.h @@ -0,0 +1,32 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H + +#include "../../proto/hedera/ConsensusSubmitMessage.pb.h" +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + + class ConsensusSubmitMessage + { + public: + ConsensusSubmitMessage(Poco::AutoPtr topicID); + ~ConsensusSubmitMessage(); + + inline proto::ConsensusSubmitMessageTransactionBody* getProtoTransactionBody() { return mConsensusMessageBody; } + inline void resetPointer() { mConsensusMessageBody = nullptr; } + void setMessage(std::string byteString); + inline void setMessage(const MemoryBin* message) { setMessage(std::string((const char*)message->data(), message->size())); } + + bool validate(); + + + + protected: + proto::ConsensusSubmitMessageTransactionBody* mConsensusMessageBody; + + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.cpp b/src/cpp/model/hedera/CryptoCreateTransaction.cpp index 696a8d6e7..1c5d58e11 100644 --- a/src/cpp/model/hedera/CryptoCreateTransaction.cpp +++ b/src/cpp/model/hedera/CryptoCreateTransaction.cpp @@ -3,14 +3,32 @@ namespace model { namespace hedera { - CryptoCreateTransaction::CryptoCreateTransaction() + CryptoCreateTransaction::CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod) { + mCryptoCreateBody = new proto::CryptoCreateTransactionBody; + // public key + auto key = mCryptoCreateBody->mutable_key(); + auto public_key = new std::string((const char*)publicKey, KeyPairHedera::getPublicKeySize()); + key->set_allocated_ed25519(public_key); + + mCryptoCreateBody->set_initialbalance(initialBalance); + + auto auto_renew_period = mCryptoCreateBody->mutable_autorenewperiod(); + auto_renew_period->set_seconds(autoRenewPeriod); + } CryptoCreateTransaction::~CryptoCreateTransaction() { - + if (mCryptoCreateBody) { + delete mCryptoCreateBody; + mCryptoCreateBody = nullptr; + } } + bool CryptoCreateTransaction::validate() + { + return true; + } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/CryptoCreateTransaction.h b/src/cpp/model/hedera/CryptoCreateTransaction.h index e1425ebf5..7182f3506 100644 --- a/src/cpp/model/hedera/CryptoCreateTransaction.h +++ b/src/cpp/model/hedera/CryptoCreateTransaction.h @@ -3,15 +3,23 @@ #include "../../proto/hedera/CryptoCreate.pb.h" +#include "../Crypto/KeyPairHedera.h" + namespace model { namespace hedera { class CryptoCreateTransaction { public: - CryptoCreateTransaction(); + //! \param publicKey newly created public key from ed25519 public-private key pair for hedera + CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod); ~CryptoCreateTransaction(); + proto::CryptoCreateTransactionBody* getProtoTransactionBody() { return mCryptoCreateBody; } + inline void resetPointer() { mCryptoCreateBody = nullptr; } + + bool validate(); + protected: proto::CryptoCreateTransactionBody* mCryptoCreateBody; }; diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.cpp b/src/cpp/model/hedera/CryptoTransferTransaction.cpp index 828a85645..171e239f4 100644 --- a/src/cpp/model/hedera/CryptoTransferTransaction.cpp +++ b/src/cpp/model/hedera/CryptoTransferTransaction.cpp @@ -43,11 +43,6 @@ namespace model { } return 0 == sum && transfers->accountamounts_size() > 0; } - - void CryptoTransferTransaction::resetPointer() - { - mCryptoTransfer = nullptr; - } } } diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.h b/src/cpp/model/hedera/CryptoTransferTransaction.h index 04aacafea..21d9bd3c3 100644 --- a/src/cpp/model/hedera/CryptoTransferTransaction.h +++ b/src/cpp/model/hedera/CryptoTransferTransaction.h @@ -26,7 +26,7 @@ namespace model { bool validate(); // set pointer to zero, after hand over pointer to transaction body - void resetPointer(); + inline void resetPointer() { mCryptoTransfer = nullptr; } inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; } diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index 4699e71ea..ab786e44f 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -18,6 +18,8 @@ namespace model { bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) { + mType = transactionBody->getType(); + auto mm = MemoryManager::getInstance(); mConnection = transactionBody->getConnection(); auto transaction_body_proto = transactionBody->getProtoTransactionBody(); @@ -40,5 +42,32 @@ namespace model { mm->releaseMemory(sign); return true; } + + bool Transaction::sign(std::unique_ptr keyPairHedera, std::unique_ptr transactionBody) + { + mType = transactionBody->getType(); + + auto mm = MemoryManager::getInstance(); + mConnection = transactionBody->getConnection(); + auto transaction_body_proto = transactionBody->getProtoTransactionBody(); + auto body_bytes = transaction_body_proto->SerializeAsString(); + mTransaction->set_bodybytes(body_bytes.data(), body_bytes.size()); + auto signature_map = mTransaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_map->add_sigpair(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + return true; + } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index d5e9434bd..fe1bfed51 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -23,14 +23,17 @@ namespace model { ~Transaction(); bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); + bool sign(std::unique_ptr keyPairHedera, std::unique_ptr transactionBody); inline proto::Transaction* getTransaction() { return mTransaction; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } void resetPointer() { mTransaction = nullptr; } + inline TransactionBodyType getType() const { return mType; } protected: proto::Transaction* mTransaction; controller::NodeServerConnection mConnection; + TransactionBodyType mType; }; } } diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index f215ada23..ea44915a8 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -3,7 +3,7 @@ namespace model { namespace hedera { TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) - : mConnection(connection) + : mConnection(connection), mHasBody(false) { connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); auto transaction_id = mTransactionBody.mutable_transactionid(); @@ -22,9 +22,15 @@ namespace model { bool TransactionBody::setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction) { + if (mHasBody) { + printf("[TransactionBody::setCryptoTransfer] has already a body\n"); + return false; + } if (cryptoTransferTransaction.validate()) { mTransactionBody.set_allocated_cryptotransfer(cryptoTransferTransaction.getProtoTransactionBody()); cryptoTransferTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CRYPTO_TRANSFER; return true; } return false; @@ -32,9 +38,47 @@ namespace model { bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction) { + if (mHasBody) { + printf("[TransactionBody::setCreateTopic] has already a body\n"); + return false; + } if (consensusCreateTopicTransaction.validate()) { mTransactionBody.set_allocated_consensuscreatetopic(consensusCreateTopicTransaction.getProtoTransactionBody()); consensusCreateTopicTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CONSENSUS_CREATE_TOPIC; + return true; + } + return false; + } + + bool TransactionBody::setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction) + { + if (mHasBody) { + printf("[TransactionBody::setCryptoCreate] has already a body\n"); + return false; + } + if (cryptoCreateTransaction.validate()) { + mTransactionBody.set_allocated_cryptocreateaccount(cryptoCreateTransaction.getProtoTransactionBody()); + cryptoCreateTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CRYPTO_CREATE; + return true; + } + return false; + } + + bool TransactionBody::setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction) + { + if (mHasBody) { + printf("[TransactionBody::setConsensusSubmitMessage] has already a body\n"); + return false; + } + if (consensusSubmitMessageTransaction.validate()) { + mTransactionBody.set_allocated_consensussubmitmessage(consensusSubmitMessageTransaction.getProtoTransactionBody()); + consensusSubmitMessageTransaction.resetPointer(); + mHasBody = true; + mType = TRANSACTION_CONSENSUS_SUBMIT_MESSAGE; return true; } return false; diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 7be8d2105..9a5406af7 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -13,12 +13,23 @@ #include "../../controller/NodeServer.h" #include "CryptoTransferTransaction.h" +#include "CryptoCreateTransaction.h" #include "ConsensusCreateTopic.h" +#include "ConsensusSubmitMessage.h" #include "../../proto/hedera/TransactionBody.pb.h" namespace model { namespace hedera { + + enum TransactionBodyType + { + TRANSACTION_CRYPTO_TRANSFER, + TRANSACTION_CRYPTO_CREATE, + TRANSACTION_CONSENSUS_CREATE_TOPIC, + TRANSACTION_CONSENSUS_SUBMIT_MESSAGE + }; + class TransactionBody { public: @@ -29,17 +40,22 @@ namespace model { void setFee(Poco::UInt64 fee); bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + bool setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction); bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction); + bool setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction); //bool inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } inline controller::NodeServerConnection getConnection() const { return mConnection; } + inline TransactionBodyType getType() const { return mType; } protected: void updateTimestamp(); proto::TransactionBody mTransactionBody; controller::NodeServerConnection mConnection; + bool mHasBody; + TransactionBodyType mType; }; } } diff --git a/src/cpp/model/hedera/TransactionResponse.cpp b/src/cpp/model/hedera/TransactionResponse.cpp new file mode 100644 index 000000000..2e9a66ea1 --- /dev/null +++ b/src/cpp/model/hedera/TransactionResponse.cpp @@ -0,0 +1,18 @@ +#include "TransactionResponse.h" + +namespace model { + namespace hedera { + + TransactionResponse::TransactionResponse() + { + + } + + TransactionResponse::~TransactionResponse() + { + + } + + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionResponse.h b/src/cpp/model/hedera/TransactionResponse.h new file mode 100644 index 000000000..325cbe73f --- /dev/null +++ b/src/cpp/model/hedera/TransactionResponse.h @@ -0,0 +1,30 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H + +#include "../../proto/hedera/TransactionResponse.pb.h" +#include "Poco/Types.h" + +namespace model { + namespace hedera { + + class TransactionResponse + { + public: + TransactionResponse(); + ~TransactionResponse(); + + inline proto::ResponseCodeEnum getPrecheckCode() const { return mProtoResponse.nodetransactionprecheckcode();} + inline std::string getPrecheckCodeString() const { return proto::ResponseCodeEnum_Name(mProtoResponse.nodetransactionprecheckcode()); } + inline Poco::UInt64 getCost() const { return mProtoResponse.cost(); } + + proto::TransactionResponse* getProtoResponse() { return &mProtoResponse; } + protected: + proto::TransactionResponse mProtoResponse; + + }; + } +} + + + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/table/HederaId.cpp b/src/cpp/model/table/HederaId.cpp index d6ceb8cb7..fce86a541 100644 --- a/src/cpp/model/table/HederaId.cpp +++ b/src/cpp/model/table/HederaId.cpp @@ -16,6 +16,13 @@ namespace model { } + HederaId::HederaId(const HederaIdTuple& tuple) + : ModelBase(tuple.get<0>()), + mShardNum(tuple.get<1>()), mRealmNum(tuple.get<2>()), mNum(tuple.get<3>()) + { + + } + HederaId::~HederaId() { diff --git a/src/cpp/model/table/HederaId.h b/src/cpp/model/table/HederaId.h index 9dc2029bc..bed00168f 100644 --- a/src/cpp/model/table/HederaId.h +++ b/src/cpp/model/table/HederaId.h @@ -7,11 +7,14 @@ namespace model { namespace table { + typedef Poco::Tuple HederaIdTuple; + class HederaId : public ModelBase { public: HederaId(); HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num); + HederaId(const HederaIdTuple& tuple); ~HederaId(); // generic db operations @@ -25,7 +28,6 @@ namespace model { inline Poco::UInt64 getRealmNum() const { return mRealmNum; } inline Poco::UInt64 getNum() const { return mNum; } - protected: Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session); diff --git a/src/cpp/tasks/HederaTask.cpp b/src/cpp/tasks/HederaTask.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/tasks/HederaTask.h b/src/cpp/tasks/HederaTask.h new file mode 100644 index 000000000..0c22da226 --- /dev/null +++ b/src/cpp/tasks/HederaTask.h @@ -0,0 +1,15 @@ +#ifndef __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H +#define __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H + +#include "../model/hedera/TransactionResponse.h" + +class HederaTask +{ +public: + inline model::hedera::TransactionResponse* getTransactionResponse() { return &mTransactionResponse; } + +protected: + model::hedera::TransactionResponse mTransactionResponse; +}; + +#endif //__GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H \ No newline at end of file diff --git a/src/cpp/tasks/SigningTransaction.cpp b/src/cpp/tasks/SigningTransaction.cpp index f28946c0c..297d2ca1d 100644 --- a/src/cpp/tasks/SigningTransaction.cpp +++ b/src/cpp/tasks/SigningTransaction.cpp @@ -1,278 +1,319 @@ -#include "SigningTransaction.h" - -#include - -#include "../SingletonManager/ErrorManager.h" -#include "../SingletonManager/MemoryManager.h" -#include "../SingletonManager/SingletonTaskObserver.h" - -#include "../lib/Profiler.h" - -#include "../proto/gradido/Transaction.pb.h" - -#include "sodium.h" - -#include "../ServerConfig.h" -#include "Poco/JSON/Object.h" -#include "Poco/JSON/Parser.h" -#include "Poco/StreamCopier.h" -#include "Poco/Net/HTTPSClientSession.h" -#include "Poco/Net/HTTPRequest.h" -#include "Poco/Net/HTTPResponse.h" - -SigningTransaction::SigningTransaction( - Poco::AutoPtr processingeTransaction, - Poco::AutoPtr newUser - , bool sendErrorsToAdmin/* = true*/) - : mProcessingeTransaction(processingeTransaction), mNewUser(newUser), mSendErrorsToAdminEmail(sendErrorsToAdmin) -{ - auto ob = SingletonTaskObserver::getInstance(); - auto email = getUserEmail(); - - if (email != "") { - ob->addTask(email, TASK_OBSERVER_SIGN_TRANSACTION); - } -} - -SigningTransaction::~SigningTransaction() -{ - auto ob = SingletonTaskObserver::getInstance(); - auto email = getUserEmail(); - - if (email != "") { - ob->removeTask(email, TASK_OBSERVER_SIGN_TRANSACTION); - } -} - -std::string SigningTransaction::getUserEmail() -{ - model::table::User* user_model = nullptr; - - if (!mNewUser.isNull()) { - user_model = mNewUser->getModel(); - } - if (user_model) { - return user_model->getEmail(); - } - return ""; -} - -int SigningTransaction::run() { - auto mm = MemoryManager::getInstance(); - - Error* transactionError = new Error("SigningTransaction", mProcessingeTransaction->mProtoMessageBase64.data()); - addError(transactionError, false); - - //= new Error("SigningTransaction start", mProcessingeTransaction->g) - //if (mUser.isNull() || !mUser->hasCryptoKey()) { - if(mNewUser.isNull() || !mNewUser->hasPassword()) { - addError(new Error("SigningTransaction", "user hasn't crypto key or is null")); - if(mSendErrorsToAdminEmail) sendErrorsAsEmail(); - return -1; - } - - //auto privKey = mUser->getPrivKey(); - //if (!mUser->hasPrivKey()) { - auto gradido_key_pair = mNewUser->getGradidoKeyPair(); - KeyPairEd25519* recovered_gradido_key_pair = nullptr; - if(!gradido_key_pair || !gradido_key_pair->hasPrivateKey()) { - - if (!mNewUser->tryLoadPassphraseUserBackup(&recovered_gradido_key_pair)) { - if(mNewUser->setGradidoKeyPair(recovered_gradido_key_pair)) - { - mNewUser->getModel()->updatePrivkey(); - } - } - else { - addError(new Error("SigningTransaction", "user cannot decrypt private key")); - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - return -2; - } - } - // get body bytes - model::messages::gradido::Transaction transaction; - auto bodyBytes = transaction.mutable_bodybytes(); - *bodyBytes = mProcessingeTransaction->getBodyBytes(); - if (*bodyBytes == "") { - getErrors(mProcessingeTransaction); - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - return -3; - } - // sign - //auto sign = mUser->sign((const unsigned char*)bodyBytes->data(), bodyBytes->size()); - MemoryBin* sign = nullptr; - if (gradido_key_pair) { - sign = gradido_key_pair->sign(*bodyBytes); - } - else if (recovered_gradido_key_pair) { - sign = recovered_gradido_key_pair->sign(*bodyBytes); - } - if (!sign) { - ErrorManager::getInstance()->sendErrorsAsEmail(); - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - mm->releaseMemory(sign); - return -4; - } - - // pubkey for signature - /*auto pubkeyBin = mm->getFreeMemory(ed25519_pubkey_SIZE); - size_t realBin = 0; - if (sodium_hex2bin(*pubkeyBin, *pubkeyBin, pubkeyHex.data(), pubkeyHex.size(), nullptr, &realBin, nullptr)) { - addError(new Error("SigningTransaction", "error in sodium_hex2bin")); - sendErrorsAsEmail(); - mm->releaseMemory(pubkeyBin); - mm->releaseMemory(sign); - return -5; - } - */ - // add to message - auto sigMap = transaction.mutable_sigmap(); - auto sigPair = sigMap->add_sigpair(); - - auto pubkeyBytes = sigPair->mutable_pubkey(); - auto pubkeyBin = mNewUser->getModel()->getPublicKey(); - *pubkeyBytes = std::string((const char*)pubkeyBin, crypto_sign_PUBLICKEYBYTES); - - - auto sigBytes = sigPair->mutable_ed25519(); - *sigBytes = std::string((char*)*sign, sign->size()); - mm->releaseMemory(sign); - - /*std::string protoPrettyPrint; - google::protobuf::TextFormat::PrintToString(transaction, &protoPrettyPrint); - printf("transaction pretty: %s\n", protoPrettyPrint.data()); - model::messages::gradido::TransactionBody transactionBody; - transactionBody.MergeFromString(transaction.bodybytes()); - google::protobuf::TextFormat::PrintToString(transactionBody, &protoPrettyPrint); - printf("transaction body pretty: \n%s\n", protoPrettyPrint.data()); - */ - // finalize - //printf("sigpair size: %d\n", transaction.sigmap().sigpair_size()); - std::string finalTransactionBin = transaction.SerializeAsString(); - if (finalTransactionBin == "") { - addError(new Error("SigningTransaction", "error serializing final transaction")); - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - return -6; - } - - // finale to base64 - auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); - auto finalBase64Bin = mm->getFreeMemory(finalBase64Size); - if (!sodium_bin2base64(*finalBase64Bin, finalBase64Size, (const unsigned char*)finalTransactionBin.data(), finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING)) { - addError(new Error("SigningTransaction", "error convert final transaction to base64")); - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - mm->releaseMemory(finalBase64Bin); - return -7; - } - addError(new Error("Signing transaction final", *finalBase64Bin), false); - - // create json request - - Poco::JSON::Object requestJson; - requestJson.set("method", "putTransaction"); - requestJson.set("transaction", std::string((char*)*finalBase64Bin)); - //printf("\nbase64 transaction: \n%s\n\n", (char*)*finalBase64Bin); - mm->releaseMemory(finalBase64Bin); - - - //std::string request = requestJson.stringify(); - - // send post request via https - // 443 = HTTPS Default - // or http via port 80 if it is a test server - // TODO: adding port into ServerConfig - bool choose_ssl = false; - try { - Profiler phpRequestTime; - Poco::Net::HTTPClientSession* clientSession = nullptr; - - if (ServerConfig::g_phpServerPort) { - clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, ServerConfig::g_phpServerPort); - choose_ssl = true; - } - else if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || - ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { - clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443); - choose_ssl = true; - } - else { - clientSession = new Poco::Net::HTTPClientSession(ServerConfig::g_php_serverHost, 80); - choose_ssl = false; - } - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); - - request.setChunkedTransferEncoding(true); - std::ostream& requestStream = clientSession->sendRequest(request); - requestJson.stringify(requestStream); - - Poco::Net::HTTPResponse response; - std::istream& request_stream = clientSession->receiveResponse(response); - - // debugging answer - - std::stringstream responseStringStream; - for (std::string line; std::getline(request_stream, line); ) { - responseStringStream << line << std::endl; - } - Poco::Logger& speedLog= Poco::Logger::get("SpeedLog"); - speedLog.information("[putTransaction] php server time: %s", phpRequestTime.string()); - - // extract parameter from request - Poco::JSON::Parser jsonParser; - Poco::Dynamic::Var parsedJson; - try { - parsedJson = jsonParser.parse(responseStringStream.str()); - } - catch (Poco::Exception& ex) { - //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); - addError(new ParamError("SigningTransaction", "error parsing request answer", ex.displayText().data())); - - FILE* f = fopen("response.html", "wt"); - if (f) { - std::string responseString = responseStringStream.str(); - fwrite(responseString.data(), 1, responseString.size(), f); - fclose(f); - } - // */ - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(responseStringStream.str()); - return -9; - } - - //sendErrorsAsEmail("HalloRote Test "); - - Poco::JSON::Object object = *parsedJson.extract(); - - std::string stateString = ""; - if (!object.isNull("state")) { - auto state = object.get("state"); - stateString = state.convert(); - } - if (stateString != "success") { - addError(new Error("SigningTransaction", "php server don't return success")); - if (!object.isNull("msg")) { - addError(new ParamError("SigningTransaction", "msg:", object.get("msg").convert().data())); - } - if (!object.isNull("details")) { - addError(new ParamError("SigningTransaction", "details:", object.get("details").convert().data())); - } - if (!object.isNull("user_error")) { - addError(new ParamError("SigningTransaction", "user_error", object.get("user_error").convert().data())); - } - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - return -10; - } - delete clientSession; - //printf("state: %s\n", stateString.data()); - //int zahl = 1; - } - catch (Poco::Exception& e) { - addError(new ParamError("SigningTransaction", "connect error to php server", e.displayText().data())); - addError(new ParamError("SigningTransaction", "url", ServerConfig::g_php_serverHost.data())); - addError(new ParamError("SigningTransaction", "choose_ssl", choose_ssl)); - if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); - return -8; - } - - - return 0; +#include "SigningTransaction.h" + +#include + +#include "../SingletonManager/ErrorManager.h" +#include "../SingletonManager/MemoryManager.h" +#include "../SingletonManager/SingletonTaskObserver.h" + +#include "../lib/Profiler.h" + +#include "../proto/gradido/Transaction.pb.h" + +#include "sodium.h" + +#include "../ServerConfig.h" +#include "Poco/JSON/Object.h" +#include "Poco/JSON/Parser.h" +#include "Poco/StreamCopier.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" + +// stuff for hedera transaction +#include "../controller/HederaAccount.h" +#include "../controller/HederaRequest.h" +#include "../model/hedera/TransactionBody.h" +#include "../model/hedera/Transaction.h" + +SigningTransaction::SigningTransaction( + Poco::AutoPtr processingeTransaction, + Poco::AutoPtr newUser, + bool sendErrorsToAdmin/* = true*/) + : mProcessingeTransaction(processingeTransaction), mNewUser(newUser), mSendErrorsToAdminEmail(sendErrorsToAdmin) +{ + auto ob = SingletonTaskObserver::getInstance(); + auto email = getUserEmail(); + + if (email != "") { + ob->addTask(email, TASK_OBSERVER_SIGN_TRANSACTION); + } +} + +SigningTransaction::~SigningTransaction() +{ + auto ob = SingletonTaskObserver::getInstance(); + auto email = getUserEmail(); + + if (email != "") { + ob->removeTask(email, TASK_OBSERVER_SIGN_TRANSACTION); + } +} + +std::string SigningTransaction::getUserEmail() +{ + model::table::User* user_model = nullptr; + + if (!mNewUser.isNull()) { + user_model = mNewUser->getModel(); + } + if (user_model) { + return user_model->getEmail(); + } + return ""; +} + +int SigningTransaction::run() { + auto mm = MemoryManager::getInstance(); + + Error* transactionError = new Error("SigningTransaction", mProcessingeTransaction->mProtoMessageBase64.data()); + addError(transactionError, false); + + //= new Error("SigningTransaction start", mProcessingeTransaction->g) + //if (mUser.isNull() || !mUser->hasCryptoKey()) { + if(mNewUser.isNull() || !mNewUser->hasPassword()) { + addError(new Error("SigningTransaction", "user hasn't crypto key or is null")); + if(mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -1; + } + + //auto privKey = mUser->getPrivKey(); + //if (!mUser->hasPrivKey()) { + auto gradido_key_pair = mNewUser->getGradidoKeyPair(); + KeyPairEd25519* recovered_gradido_key_pair = nullptr; + if(!gradido_key_pair || !gradido_key_pair->hasPrivateKey()) { + + if (!mNewUser->tryLoadPassphraseUserBackup(&recovered_gradido_key_pair)) { + if(mNewUser->setGradidoKeyPair(recovered_gradido_key_pair)) + { + mNewUser->getModel()->updatePrivkey(); + } + } + else { + addError(new Error("SigningTransaction", "user cannot decrypt private key")); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -2; + } + } + // get body bytes + model::messages::gradido::Transaction transaction; + auto bodyBytes = transaction.mutable_bodybytes(); + *bodyBytes = mProcessingeTransaction->getBodyBytes(); + if (*bodyBytes == "") { + getErrors(mProcessingeTransaction); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -3; + } + // sign + //auto sign = mUser->sign((const unsigned char*)bodyBytes->data(), bodyBytes->size()); + MemoryBin* sign = nullptr; + if (gradido_key_pair) { + sign = gradido_key_pair->sign(*bodyBytes); + } + else if (recovered_gradido_key_pair) { + sign = recovered_gradido_key_pair->sign(*bodyBytes); + } + if (!sign) { + ErrorManager::getInstance()->sendErrorsAsEmail(); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + mm->releaseMemory(sign); + return -4; + } + + // pubkey for signature + /*auto pubkeyBin = mm->getFreeMemory(ed25519_pubkey_SIZE); + size_t realBin = 0; + if (sodium_hex2bin(*pubkeyBin, *pubkeyBin, pubkeyHex.data(), pubkeyHex.size(), nullptr, &realBin, nullptr)) { + addError(new Error("SigningTransaction", "error in sodium_hex2bin")); + sendErrorsAsEmail(); + mm->releaseMemory(pubkeyBin); + mm->releaseMemory(sign); + return -5; + } + */ + // add to message + auto sigMap = transaction.mutable_sigmap(); + auto sigPair = sigMap->add_sigpair(); + + auto pubkeyBytes = sigPair->mutable_pubkey(); + auto pubkeyBin = mNewUser->getModel()->getPublicKey(); + *pubkeyBytes = std::string((const char*)pubkeyBin, crypto_sign_PUBLICKEYBYTES); + + + auto sigBytes = sigPair->mutable_ed25519(); + *sigBytes = std::string((char*)*sign, sign->size()); + mm->releaseMemory(sign); + + /*std::string protoPrettyPrint; + google::protobuf::TextFormat::PrintToString(transaction, &protoPrettyPrint); + printf("transaction pretty: %s\n", protoPrettyPrint.data()); + model::messages::gradido::TransactionBody transactionBody; + transactionBody.MergeFromString(transaction.bodybytes()); + google::protobuf::TextFormat::PrintToString(transactionBody, &protoPrettyPrint); + printf("transaction body pretty: \n%s\n", protoPrettyPrint.data()); + */ + // finalize + //printf("sigpair size: %d\n", transaction.sigmap().sigpair_size()); + std::string finalTransactionBin = transaction.SerializeAsString(); + if (finalTransactionBin == "") { + addError(new Error("SigningTransaction", "error serializing final transaction")); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -6; + } + + auto network_type = model::table::HEDERA_TESTNET; + auto topic_id = controller::HederaId::find(1, network_type); + auto hedera_operator_account = controller::HederaAccount::pick(network_type, false); + + if (!topic_id.isNull() && !hedera_operator_account.isNull()) { + auto crypto_key = hedera_operator_account->getCryptoKey(); + if (!crypto_key.isNull()) { + model::hedera::ConsensusSubmitMessage consensus_submit_message(topic_id); + consensus_submit_message.setMessage(finalTransactionBin); + auto hedera_transaction_body = hedera_operator_account->createTransactionBody(); + hedera_transaction_body->setConsensusSubmitMessage(consensus_submit_message); + model::hedera::Transaction hedera_transaction; + hedera_transaction.sign(crypto_key->getKeyPair(), std::move(hedera_transaction_body)); + + HederaRequest hedera_request; + HederaTask hedera_task;// placeholder + if (HEDERA_REQUEST_RETURN_OK != hedera_request.request(&hedera_transaction, &hedera_task)) { + addError(new Error("SigningTransaction", "error send transaction to hedera")); + getErrors(&hedera_request); + sendErrorsAsEmail(); + } + else { + auto hedera_precheck_code_string = hedera_task.getTransactionResponse()->getPrecheckCodeString(); + printf("hedera response: %s\n", hedera_precheck_code_string.data()); + } + //model::hedera::TransactionBody hedera_transaction_body() + } + else { + printf("[SigningTransaction] crypto key not found\n"); + } + } + else { + printf("[SigningTransaction] hedera topic id or operator account not found\n"); + } + + // finale to base64 + auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); + auto finalBase64Bin = mm->getFreeMemory(finalBase64Size); + if (!sodium_bin2base64(*finalBase64Bin, finalBase64Size, (const unsigned char*)finalTransactionBin.data(), finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING)) { + addError(new Error("SigningTransaction", "error convert final transaction to base64")); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + mm->releaseMemory(finalBase64Bin); + return -7; + } + addError(new Error("Signing transaction final", *finalBase64Bin), false); + + // create json request + + Poco::JSON::Object requestJson; + requestJson.set("method", "putTransaction"); + requestJson.set("transaction", std::string((char*)*finalBase64Bin)); + //printf("\nbase64 transaction: \n%s\n\n", (char*)*finalBase64Bin); + mm->releaseMemory(finalBase64Bin); + + + //std::string request = requestJson.stringify(); + + // send post request via https + // 443 = HTTPS Default + // or http via port 80 if it is a test server + // TODO: adding port into ServerConfig + bool choose_ssl = false; + try { + Profiler phpRequestTime; + Poco::Net::HTTPClientSession* clientSession = nullptr; + + if (ServerConfig::g_phpServerPort) { + clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, ServerConfig::g_phpServerPort); + choose_ssl = true; + } + else if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || + ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { + clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443); + choose_ssl = true; + } + else { + clientSession = new Poco::Net::HTTPClientSession(ServerConfig::g_php_serverHost, 80); + choose_ssl = false; + } + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); + + request.setChunkedTransferEncoding(true); + std::ostream& requestStream = clientSession->sendRequest(request); + requestJson.stringify(requestStream); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = clientSession->receiveResponse(response); + + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + Poco::Logger& speedLog= Poco::Logger::get("SpeedLog"); + speedLog.information("[putTransaction] php server time: %s", phpRequestTime.string()); + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + } + catch (Poco::Exception& ex) { + //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); + addError(new ParamError("SigningTransaction", "error parsing request answer", ex.displayText().data())); + + FILE* f = fopen("response.html", "wt"); + if (f) { + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + } + // */ + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(responseStringStream.str()); + return -9; + } + + //sendErrorsAsEmail("HalloRote Test "); + + Poco::JSON::Object object = *parsedJson.extract(); + + std::string stateString = ""; + if (!object.isNull("state")) { + auto state = object.get("state"); + stateString = state.convert(); + } + if (stateString != "success") { + addError(new Error("SigningTransaction", "php server don't return success")); + if (!object.isNull("msg")) { + addError(new ParamError("SigningTransaction", "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError("SigningTransaction", "details:", object.get("details").convert().data())); + } + if (!object.isNull("user_error")) { + addError(new ParamError("SigningTransaction", "user_error", object.get("user_error").convert().data())); + } + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -10; + } + delete clientSession; + //printf("state: %s\n", stateString.data()); + //int zahl = 1; + } + catch (Poco::Exception& e) { + addError(new ParamError("SigningTransaction", "connect error to php server", e.displayText().data())); + addError(new ParamError("SigningTransaction", "url", ServerConfig::g_php_serverHost.data())); + addError(new ParamError("SigningTransaction", "choose_ssl", choose_ssl)); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail();); + return -8; + } + + + return 0; } \ No newline at end of file diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index b55701b1b..d3d68b82c 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -24,6 +24,9 @@ auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + int auto_renew_period = 604800; // 7 Tage + int auto_renew_account = 0; + double initial_balance = 0.0; Profiler hedera_time; std::string hedera_time_string; @@ -59,8 +62,11 @@ if(action == "updateBalance") { hedera_time.reset(); - query_hedera_account->hederaAccountGetBalance(user); - addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + if(query_hedera_account->hederaAccountGetBalance(user)) { + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); + } else { + addError(new ParamError("Hedera", "crypto get balance failed in ", hedera_time.string())); + } } else if(action == "changeEncryption") { @@ -69,113 +75,150 @@ } } } - else if(!form.empty()) // add + else if(!form.empty()) // add or create { - // collect - auto shardNumString = form.get("account-shard-num", "0"); - auto realmNumString = form.get("account-realm-num", "0"); - auto numString = form.get("account-num", "0"); - auto privateKeyString = form.get("account-private-key", ""); - auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); - auto publicKeyString = form.get("account-public-key", ""); - auto networkTypeString = form.get("account-network-type", "0"); + auto creationButton = form.get("create",""); + if(creationButton != "") { - //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); - - int shardNum = 0; - int realmNum = 0; - int num = 0; - int networkType = 0; - - MemoryBin* private_key = nullptr; - MemoryBin* public_key = nullptr; - - // validate - if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "shard num not integer")); - } else { - if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting shardNumString to int")); - } - } - if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "realm num not integer")); - } else { - if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting realmNumString to int")); - } - } - if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Account ID", "num not integer")); - } else { - if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting num to int")); - } - } - if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "private key not hex")); - } - if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { - addError(new Error("Account Keys", "public key not hex")); - } - if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { - addError(new Error("Network Type", "not integer")); - } else { - if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { - addError(new Error("Int Convert Error", "Error converting network type to int")); - } - if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { - addError(new Error("Network Type", "invalid value")); - } - } - - if(0 == errorCount()) { - - auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + // collect + auto auto_renew_account_string = form.get("account-auto-renew-account", "0"); + auto auto_renew_period_string = form.get("account-auto-renew-period", "604800"); + auto account_initial_balance_string = form.get("account-initial-balance", "0"); - private_key = DataTypeConverter::hexToBin(privateKeyString); - public_key = DataTypeConverter::hexToBin(publicKeyString); - - - KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); - - if(crypto_key.isNull()) { - crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); - if(!crypto_key->getModel()->insertIntoDB(true)) { - addError(new Error("DB Error", "Error saving crypto key in DB")); - } + if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew account id not an integer")); } else { - printf("crypto key found in db\n"); - } - if(0 == errorCount()) { - - if(hedera_id->isExistInDB()) { - auto hedera_account = controller::HederaAccount::load(hedera_id); - if(hedera_account.isNull()) { - addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); - } else { - addError(new Error("Hedera Account", "Account already exist (same account id")); - } - - } else { - auto hedera_account = controller::HederaAccount::create( - user->getModel()->getID(), - hedera_id->getModel()->getID(), - crypto_key->getModel()->getID(), - 0, - (model::table::HederaNetworkType)networkType - ); - if(!hedera_account->getModel()->insertIntoDB(false)) { - addError(new Error("DB Error", "Error saving hedera account into DB")); - } + if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew account id to int")); } } - mm->releaseMemory(private_key); - mm->releaseMemory(public_key); - } + if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account", "auto renew period not an integer")); + } else { + if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int convert error", "Error converting auto renew period to int")); + } + } + + if(!sm->isValid(account_initial_balance_string, VALIDATE_ONLY_DECIMAL)) { + addError(new Error("Account", "initial balance not an decimal")); + } else { + if(DataTypeConverter::strToDouble(account_initial_balance_string, initial_balance) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Double convert error", "Error converting initial balance to double")); + } + } + if(0 == errorCount()) + { + } + + } else { + // collect + auto shardNumString = form.get("account-shard-num", "0"); + auto realmNumString = form.get("account-realm-num", "0"); + auto numString = form.get("account-num", "0"); + auto privateKeyString = form.get("account-private-key", ""); + auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false"); + auto publicKeyString = form.get("account-public-key", ""); + auto networkTypeString = form.get("account-network-type", "0"); + + //printf("private key encrypted: %s\n", privateKeyEncryptedString.data()); + + int shardNum = 0; + int realmNum = 0; + int num = 0; + int networkType = 0; + + MemoryBin* private_key = nullptr; + MemoryBin* public_key = nullptr; + + // validate + if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "shard num not integer")); + } else { + if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting shardNumString to int")); + } + } + if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "realm num not integer")); + } else { + if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting realmNumString to int")); + } + } + if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Account ID", "num not integer")); + } else { + if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting num to int")); + } + } + if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "private key not hex")); + } + if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) { + addError(new Error("Account Keys", "public key not hex")); + } + if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Network Type", "not integer")); + } else { + if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting network type to int")); + } + if(networkType < 0 || networkType >= (int)model::table::HEDERA_NET_COUNT) { + addError(new Error("Network Type", "invalid value")); + } + } + + if(0 == errorCount()) { + + auto hedera_id = controller::HederaId::create(shardNum, realmNum, num); + + private_key = DataTypeConverter::hexToBin(privateKeyString); + public_key = DataTypeConverter::hexToBin(publicKeyString); + + + KeyPairHedera key_pair(private_key, public_key); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + + if(crypto_key.isNull()) { + crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); + if(!crypto_key->getModel()->insertIntoDB(true)) { + addError(new Error("DB Error", "Error saving crypto key in DB")); + } + } else { + printf("crypto key found in db\n"); + } + if(0 == errorCount()) { + + if(hedera_id->isExistInDB()) { + auto hedera_account = controller::HederaAccount::load(hedera_id); + if(hedera_account.isNull()) { + addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist")); + } else { + addError(new Error("Hedera Account", "Account already exist (same account id")); + } + + } else { + auto hedera_account = controller::HederaAccount::create( + user->getModel()->getID(), + hedera_id->getModel()->getID(), + crypto_key->getModel()->getID(), + 0, + (model::table::HederaNetworkType)networkType + ); + if(!hedera_account->getModel()->insertIntoDB(false)) { + addError(new Error("DB Error", "Error saving hedera account into DB")); + } + } + } + + mm->releaseMemory(private_key); + mm->releaseMemory(public_key); + } + } } if(!query_hedera_account.isNull()) { getErrors(query_hedera_account); @@ -184,6 +227,14 @@ auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID()); %><%@ include file="header_large.cpsp" %> + <%= getErrorsHtml() %>
    @@ -207,13 +258,14 @@ if(hedera_account_model->getUserId() == user->getModel()->getID()) { changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID()); } + auto isEncrypted = (*it)->getCryptoKey()->getModel()->isEncrypted(); //printf("change encryption: %s\n", changeEncryption.data()); %>
    <%= (*it)->getHederaId()->getModel()->toString() %>
    <%= hedera_account_model->getBalanceDouble() %> hbar
    <%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %>
    -
    <%= (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" %>
    +
    "><%= isEncrypted ? "Ja": "Nein" %>
    <%= hedera_account_model->getUpdatedString() %>
    -

    Einen neuen Account anlegen

    +

    Ein existierenden Account eintragen

    @@ -248,8 +300,39 @@ <% } %> - "> + "> +
    +
    +
    +

    Ein neuen Account anlegen

    +

    Bei Hedera einen neuen Account anlegen und zum Start Hashbars von einem existierenden Account überweisen.

    +
    +
    +
    + + + +
    + + + ">
    <%@ include file="footer.cpsp" %> + + From 53c8441508efca6f8f46c542fafdcc4a91aef4cf Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 15 Sep 2020 14:34:13 +0200 Subject: [PATCH 077/195] add tests for hedera account and hedera id for faster fixing mysql error --- CMakeLists.txt | 3 +- src/cpp/test/controller/TestHederaAccount.cpp | 14 ++ src/cpp/test/controller/TestHederaAccount.h | 13 ++ src/cpp/test/controller/TestHederaId.cpp | 14 ++ src/cpp/test/controller/TestHederaId.h | 13 ++ src/cpp/test/controller/TestHederaTopic.cpp | 0 src/cpp/test/controller/TestHederaTopic.h | 0 src/cpp/test/main.cpp | 196 ++++++++++++++++++ 8 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 src/cpp/test/controller/TestHederaAccount.cpp create mode 100644 src/cpp/test/controller/TestHederaAccount.h create mode 100644 src/cpp/test/controller/TestHederaId.cpp create mode 100644 src/cpp/test/controller/TestHederaId.h create mode 100644 src/cpp/test/controller/TestHederaTopic.cpp create mode 100644 src/cpp/test/controller/TestHederaTopic.h diff --git a/CMakeLists.txt b/CMakeLists.txt index be4388e9b..ac067c78e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,11 +213,12 @@ enable_testing() add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) 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 absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf -pthread) endif(WIN32) diff --git a/src/cpp/test/controller/TestHederaAccount.cpp b/src/cpp/test/controller/TestHederaAccount.cpp new file mode 100644 index 000000000..2300dc60b --- /dev/null +++ b/src/cpp/test/controller/TestHederaAccount.cpp @@ -0,0 +1,14 @@ +#include "TestHederaAccount.h" +#include "../SingletonManager/ConnectionManager.h" +namespace controller { + + void TestHederaAccount::SetUp() + { + + } + + TEST_F(TestHederaAccount, TestPick) { + auto hedera_account = controller::HederaAccount::pick(model::table::HEDERA_TESTNET, false); + EXPECT_FALSE(hedera_account.isNull()); + } +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaAccount.h b/src/cpp/test/controller/TestHederaAccount.h new file mode 100644 index 000000000..7e8e7843a --- /dev/null +++ b/src/cpp/test/controller/TestHederaAccount.h @@ -0,0 +1,13 @@ +#include "gtest/gtest.h" + +#include "../controller/HederaAccount.h" + + +namespace controller { + + class TestHederaAccount : public ::testing::Test { + protected: + void SetUp() override; + }; + +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaId.cpp b/src/cpp/test/controller/TestHederaId.cpp new file mode 100644 index 000000000..ad17e0933 --- /dev/null +++ b/src/cpp/test/controller/TestHederaId.cpp @@ -0,0 +1,14 @@ +#include "TestHederaId.h" +#include "../SingletonManager/ConnectionManager.h" +namespace controller { + + void TestHederaId::SetUp() + { + + } + + TEST_F(TestHederaId, TestFindTopicId) { + auto hedera_topic_id = controller::HederaId::find(1, model::table::HEDERA_TESTNET); + EXPECT_FALSE(hedera_topic_id.isNull()); + } +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaId.h b/src/cpp/test/controller/TestHederaId.h new file mode 100644 index 000000000..b6e4b574e --- /dev/null +++ b/src/cpp/test/controller/TestHederaId.h @@ -0,0 +1,13 @@ +#include "gtest/gtest.h" + +#include "../controller/HederaId.h" + + +namespace controller { + + class TestHederaId : public ::testing::Test { + protected: + void SetUp() override; + }; + +} \ No newline at end of file diff --git a/src/cpp/test/controller/TestHederaTopic.cpp b/src/cpp/test/controller/TestHederaTopic.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/test/controller/TestHederaTopic.h b/src/cpp/test/controller/TestHederaTopic.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/test/main.cpp b/src/cpp/test/main.cpp index 5fcab4163..62482c664 100644 --- a/src/cpp/test/main.cpp +++ b/src/cpp/test/main.cpp @@ -8,6 +8,8 @@ #include "../SingletonManager/ConnectionManager.h" +#include "../lib/Profiler.h" + std::list gTests; @@ -20,6 +22,21 @@ void fillTests() // gTests.push_back(new LoginTest()); } +void runMysql(std::string sqlQuery) +{ + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + Poco::Data::Statement mysqlStatement(session); + mysqlStatement << sqlQuery; + + try { + mysqlStatement.execute(true); + } + catch (Poco::Exception& ex) { + printf("exception in runMysql: %s\n", ex.displayText().data()); + } +} + int load() { // init server config, init seed array @@ -54,7 +71,186 @@ int load() { //printf("try connect php server mysql \n"); conn->setConnectionsFromConfig(*test_config, CONNECTION_MYSQL_PHP_SERVER); + Profiler timeUsed; + // clean up and fill db + std::string tables[] = { + "hedera_accounts", + "hedera_ids", + "crypto_keys", + "hedera_topics", + "groups", + "node_servers", + "users" + }; + for (int i = 0; i < 7; i++) { + runMysql("TRUNCATE " + tables[i]); + runMysql("ALTER TABLE " + tables[i] + " AUTO_INCREMENT = 1"); + } + + std::stringstream ss; + ss << "INSERT INTO `users` (`id`, `email`, `first_name`, `last_name`, `password`, `pubkey`, `privkey`, `created`, `email_checked`, `passphrase_shown`, `language`, `disabled`) VALUES " + << "(1, 'einhorn_silas@ist-allein.info', 'DDD', 'Schultz', 13134558453895551556, 0x146d3fb9e88abc0fca0b0091c1ab1b32b399be037436f340befa8bf004461889, 0x0dcc08960f45f631fe23bc7ddee0724cedc9ec0c861ce30f5091d20ffd96062d08ca215726fb9bd64860c754772e945eea4cc872ed0a36c7b640e8b0bf7a873ec6765fa510711622341347ce2307b5ce, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(2, 'Dario.Rekowski@buerotiger.de', 'Darios', 'Bruder', 12910944485867375321, 0x952e215a21d4376b4ac252c4bf41e156e1498e1b6b8ccf2a6826d96712f4f461, 0x4d40bf0860655f728312140dc3741e897bc2d13d00ea80a63e2961046a5a7bd8315397dfb488b89377087bc1a5f4f3af8ffdcf203329ae23ba04be7d38ad3852699d90ff1fc00e5b1ca92b64cc59c01f, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(3, 'morgenstern175@es-ist-liebe.de', 'Dieter', 'Schultz', 13528673707291575501, 0xb539944bf6444a2bfc988244f0c0c9dc326452be9b8a2a43fcd90663719f4f6d, 0x5461fda60b719b65ba00bd6298e48410c4cbf0e89deb13cc784ba8978cf047454e8556ee3eddc8487ee835c33a83163bc8d8babbf2a5c431876bc0a0c114ff0a0d6b57baa12cf8f23c64fb642c862db5, '2020-02-20 16:05:45', 1, 0, 'de', 0), " + << "(4, 'spaceteam@gmx.de', 'Bernd', 'Hückstädt', 15522411320147607375, 0x476b059744f08b0995522b484c90f8d2f47d9b59f4b3c96d9dc0ae6ab7b84979, 0x5277bf044cba4fec64e6f4d38da132755b029161231daefc9a7b4692ad37e05cdd88e0a2c2215baf854dd3a813578c214167af1113607e9f999ca848a7598ba5068e38f2a1afb097e4752a88024d79c8, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(5, 'em741@gmx.de', 'Thomas', 'Markuk', 7022671043835614958, 0xb1584e169d60a7e771d3a348235dfd7b5f9e8235fcc26090761a0264b0daa6ff, 0xb46fb7110bf91e28f367aa80f84d1bbd639b6f689f4b0aa28c0f71529232df9bf9ee0fb02fa4c1b9f5a6799c82d119e5646f7231d011517379faaacf6513d973ac3043d4c786490ba62d56d75b86164d, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(6, 'coin-info12@gradido.net', 'coin-info12', 'Test', 1548398919826089202, 0x4046ae49c1b620f2a321aba0c874fa2bc7ba844ab808bb0eeb18a908d468db14, 0x9522657ecd7456eedf86d065aa087ba7a94a8961a8e4950d044136155d38fe0840f2c0a2876ce055b3eaa6e9ab95c5feba89e535e0434fb2648d94d6e6ec68211aa2ea9e42d1ccd40b6b3c31e41f848e, '2020-02-20 16:05:47', 1, 0, 'de', 0), " + << "(7, 'info@einhornimmond.de', 'Alex', 'Wesper', 5822761891727948301, 0xb13ede3402abb8f29722b14fec0a2006ae7a3a51fb677cd6a2bbd797ac6905a5, 0x6aa39d7670c64a31639c7d89b874ad929b2eaeb2e5992dbad71b6cea700bf9e3c6cf866d0f0fdc22b44a0ebf51a860799e880ef86266199931dd0a301e5552db44b9b7fa99ed5945652bc7b31eff767c, '2020-02-20 16:05:47', 1, 0, 'de', 0); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `description`) VALUES " + << "(1, 'gdd1', 'Gradido1', 'gdd1.gradido.com', 'Der erste offizielle Gradido Server (zum Testen)'); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES " + << "(1, 2, 15, 1, 1000000000000, 1, '2020-09-03 11:13:52'), " + << "(2, 2, 17, 2, 22787166159, 0, '2020-09-03 11:13:56'); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES " + << "(1, 0, 0, 3), " + << "(2, 0, 0, 4)," + << "(3, 0, 0, 5)," + << "(4, 0, 0, 6)," + << "(6, 0, 0, 3)," + << "(10, 0, 0, 7)," + << "(11, 0, 0, 8)," + << "(12, 0, 0, 9)," + << "(13, 0, 0, 10)," + << "(14, 0, 0, 12)," + << "(15, 0, 0, 3327)," + << "(16, 0, 0, 3323)," + << "(17, 0, 0, 8707)," + << "(18, 0, 0, 39446);"; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `crypto_keys` (`id`, `private_key`, `public_key`, `crypto_key_type_id`) VALUES " + << "(1, 0xd2d4735174e6d2577573a0ec2767fba6511b1e37cd1cd98674912797fd37e12373d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 0x73d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 3), " + << "(2, 0xf1c3285be6ef869a2a8deef6caee56a5a7c2660e2bce24f39e420dd8d42fe8894bd027b2799e46dc7111a4fdd0eac3848054331f844a358de15c5b0ed3eb1740fab13ecb5a271d480e040c9266bcd584, 0xd6f6d29fb277f86ac7c3098dc799028974223e8dce6b1dd57b03940bf35fae7f, 1); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `updated`) VALUES " + << "(1, 18, 'from Pauls created with his python script', 1, 0, 1, NULL, NULL, '1999-12-31 23:00:00', 0, '2020-09-14 18:29:04'); "; + runMysql(ss.str()); + ss.str(std::string()); + + ss << "INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES " + << "(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'), " + << "(2, 'http://1.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00'), " + << "(3, 'http://2.testnet.hedera.com', 50211, 0, 4, 3, '2000-01-01 00:00:00'), " + << "(4, 'http://3.testnet.hedera.com', 50211, 0, 4, 4, '2000-01-01 00:00:00'), " + << "(5, 'http://35.237.200.180', 50211, 0, 3, 6, '2000-01-01 00:00:00'), " + << "(6, 'http://35.186.191.247', 50211, 0, 3, 2, '2000-01-01 00:00:00'), " + << "(7, 'http://35.192.2.25', 50211, 0, 3, 3, '2000-01-01 00:00:00'), " + << "(8, 'http://35.199.161.108', 50211, 0, 3, 4, '2000-01-01 00:00:00'), " + << "(9, 'http://35.203.82.240', 50211, 0, 3, 10, '2000-01-01 00:00:00'), " + << "(10, 'http://35.236.5.219', 50211, 0, 3, 11, '2000-01-01 00:00:00'), " + << "(11, 'http://35.197.192.225', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(12, 'http://35.242.233.154', 50211, 0, 3, 13, '2000-01-01 00:00:00'), " + << "(13, 'http://35.240.118.96', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(14, 'http://35.204.86.32', 50211, 0, 3, 14, '2000-01-01 00:00:00'), " + << "(15, 'https://gradido.dario-rekowski.de/', 443, 1, 2, 0, '2000-01-01 00:00:00'), " + << "(16, 'http://192.168.178.232', 8340, 1, 1, 0, '2000-01-01 00:00:00'); "; + runMysql(ss.str()); + + printf("init db in : %s\n", timeUsed.string().data()); + + /*mysqlStatement + << "TRUNCATE hedera_accounts; " + << "ALTER TABLE hedera_accounts AUTO_INCREMENT = 1; " + << "TRUNCATE hedera_ids; " + << "ALTER TABLE hedera_ids AUTO_INCREMENT = 1; " + << "TRUNCATE crypto_keys; " + << "ALTER TABLE crypto_keys AUTO_INCREMENT = 1; " + << "TRUNCATE hedera_topics; " + << "ALTER TABLE hedera_topics AUTO_INCREMENT = 1; " + << "TRUNCATE groups; " + << "ALTER TABLE groups AUTO_INCREMENT = 1; " + << "TRUNCATE node_servers; " + << "ALTER TABLE node_servers AUTO_INCREMENT = 1; " + << "TRUNCATE users; " + << "ALTER TABLE users AUTO_INCREMENT = 1; " + ; + + try { + mysqlStatement.execute(true); + } + catch (Poco::Exception& ex) { + printf("exception by cleaning up db: %s\n", ex.displayText().data()); + } + mysqlStatement.reset(session); + mysqlStatement + << "INSERT INTO `users` (`id`, `email`, `first_name`, `last_name`, `password`, `pubkey`, `privkey`, `created`, `email_checked`, `passphrase_shown`, `language`, `disabled`) VALUES " + << "(1, 'einhorn_silas@ist-allein.info', 'DDD', 'Schultz', 13134558453895551556, 0x146d3fb9e88abc0fca0b0091c1ab1b32b399be037436f340befa8bf004461889, 0x0dcc08960f45f631fe23bc7ddee0724cedc9ec0c861ce30f5091d20ffd96062d08ca215726fb9bd64860c754772e945eea4cc872ed0a36c7b640e8b0bf7a873ec6765fa510711622341347ce2307b5ce, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(2, 'Dario.Rekowski@buerotiger.de', 'Darios', 'Bruder', 12910944485867375321, 0x952e215a21d4376b4ac252c4bf41e156e1498e1b6b8ccf2a6826d96712f4f461, 0x4d40bf0860655f728312140dc3741e897bc2d13d00ea80a63e2961046a5a7bd8315397dfb488b89377087bc1a5f4f3af8ffdcf203329ae23ba04be7d38ad3852699d90ff1fc00e5b1ca92b64cc59c01f, '2020-02-20 16:05:44', 1, 0, 'de', 0), " + << "(3, 'morgenstern175@es-ist-liebe.de', 'Dieter', 'Schultz', 13528673707291575501, 0xb539944bf6444a2bfc988244f0c0c9dc326452be9b8a2a43fcd90663719f4f6d, 0x5461fda60b719b65ba00bd6298e48410c4cbf0e89deb13cc784ba8978cf047454e8556ee3eddc8487ee835c33a83163bc8d8babbf2a5c431876bc0a0c114ff0a0d6b57baa12cf8f23c64fb642c862db5, '2020-02-20 16:05:45', 1, 0, 'de', 0), " + << "(4, 'spaceteam@gmx.de', 'Bernd', 'Hückstädt', 15522411320147607375, 0x476b059744f08b0995522b484c90f8d2f47d9b59f4b3c96d9dc0ae6ab7b84979, 0x5277bf044cba4fec64e6f4d38da132755b029161231daefc9a7b4692ad37e05cdd88e0a2c2215baf854dd3a813578c214167af1113607e9f999ca848a7598ba5068e38f2a1afb097e4752a88024d79c8, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(5, 'em741@gmx.de', 'Thomas', 'Markuk', 7022671043835614958, 0xb1584e169d60a7e771d3a348235dfd7b5f9e8235fcc26090761a0264b0daa6ff, 0xb46fb7110bf91e28f367aa80f84d1bbd639b6f689f4b0aa28c0f71529232df9bf9ee0fb02fa4c1b9f5a6799c82d119e5646f7231d011517379faaacf6513d973ac3043d4c786490ba62d56d75b86164d, '2020-02-20 16:05:46', 1, 0, 'de', 0), " + << "(6, 'coin-info12@gradido.net', 'coin-info12', 'Test', 1548398919826089202, 0x4046ae49c1b620f2a321aba0c874fa2bc7ba844ab808bb0eeb18a908d468db14, 0x9522657ecd7456eedf86d065aa087ba7a94a8961a8e4950d044136155d38fe0840f2c0a2876ce055b3eaa6e9ab95c5feba89e535e0434fb2648d94d6e6ec68211aa2ea9e42d1ccd40b6b3c31e41f848e, '2020-02-20 16:05:47', 1, 0, 'de', 0), " + << "(7, 'info@einhornimmond.de', 'Alex', 'Wesper', 5822761891727948301, 0xb13ede3402abb8f29722b14fec0a2006ae7a3a51fb677cd6a2bbd797ac6905a5, 0x6aa39d7670c64a31639c7d89b874ad929b2eaeb2e5992dbad71b6cea700bf9e3c6cf866d0f0fdc22b44a0ebf51a860799e880ef86266199931dd0a301e5552db44b9b7fa99ed5945652bc7b31eff767c, '2020-02-20 16:05:47', 1, 0, 'de', 0); " + + << "INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `description`) VALUES " + << "(1, 'gdd1', 'Gradido1', 'gdd1.gradido.com', 'Der erste offizielle Gradido Server (zum Testen)'); " + + << "INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES " + << "(1, 2, 15, 1, 1000000000000, 1, '2020-09-03 11:13:52'), " + << "(2, 2, 17, 2, 22787166159, 0, '2020-09-03 11:13:56'); " + + << "INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES " + << "(1, 0, 0, 3), " + << "(2, 0, 0, 4)," + << "(3, 0, 0, 5)," + << "(4, 0, 0, 6)," + << "(6, 0, 0, 3)," + << "(10, 0, 0, 7)," + << "(11, 0, 0, 8)," + << "(12, 0, 0, 9)," + << "(13, 0, 0, 10)," + << "(14, 0, 0, 12)," + << "(15, 0, 0, 3327)," + << "(16, 0, 0, 3323)," + << "(17, 0, 0, 8707)," + << "(18, 0, 0, 39446);" + + << "INSERT INTO `crypto_keys` (`id`, `private_key`, `public_key`, `crypto_key_type_id`) VALUES " + << "(1, 0xd2d4735174e6d2577573a0ec2767fba6511b1e37cd1cd98674912797fd37e12373d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 0x73d6b4d771034cc114f80b2afb2956b6b3e020ddea2db1142c61f3fa87c72a6c, 3), " + << "(2, 0xf1c3285be6ef869a2a8deef6caee56a5a7c2660e2bce24f39e420dd8d42fe8894bd027b2799e46dc7111a4fdd0eac3848054331f844a358de15c5b0ed3eb1740fab13ecb5a271d480e040c9266bcd584, 0xd6f6d29fb277f86ac7c3098dc799028974223e8dce6b1dd57b03940bf35fae7f, 1); " + + << "INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `updated`) VALUES " + << "(1, 18, 'from Pauls created with his python script', 1, 0, 1, NULL, NULL, '1999-12-31 23:00:00', 0, '2020-09-14 18:29:04'); " + + << "INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES " + << "(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'), " + << "(2, 'http://1.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00'), " + << "(3, 'http://2.testnet.hedera.com', 50211, 0, 4, 3, '2000-01-01 00:00:00'), " + << "(4, 'http://3.testnet.hedera.com', 50211, 0, 4, 4, '2000-01-01 00:00:00'), " + << "(5, 'http://35.237.200.180', 50211, 0, 3, 6, '2000-01-01 00:00:00'), " + << "(6, 'http://35.186.191.247', 50211, 0, 3, 2, '2000-01-01 00:00:00'), " + << "(7, 'http://35.192.2.25', 50211, 0, 3, 3, '2000-01-01 00:00:00'), " + << "(8, 'http://35.199.161.108', 50211, 0, 3, 4, '2000-01-01 00:00:00'), " + << "(9, 'http://35.203.82.240', 50211, 0, 3, 10, '2000-01-01 00:00:00'), " + << "(10, 'http://35.236.5.219', 50211, 0, 3, 11, '2000-01-01 00:00:00'), " + << "(11, 'http://35.197.192.225', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(12, 'http://35.242.233.154', 50211, 0, 3, 13, '2000-01-01 00:00:00'), " + << "(13, 'http://35.240.118.96', 50211, 0, 3, 12, '2000-01-01 00:00:00'), " + << "(14, 'http://35.204.86.32', 50211, 0, 3, 14, '2000-01-01 00:00:00'), " + << "(15, 'https://gradido.dario-rekowski.de/', 443, 1, 2, 0, '2000-01-01 00:00:00'), " + << "(16, 'http://192.168.178.232', 8340, 1, 1, 0, '2000-01-01 00:00:00'); " + ; + + try { + mysqlStatement.execute(); + } + catch (Poco::Exception& ex) { + printf("exception by init db with data: %s\n", ex.displayText().data()); + } + */ fillTests(); for (std::list::iterator it = gTests.begin(); it != gTests.end(); it++) { From 5182953d0f3bb62b49ea760e8bb45559b13d937d Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 15 Sep 2020 14:35:12 +0200 Subject: [PATCH 078/195] fix mysql error, cast enum to int before using in poco data use --- src/cpp/controller/HederaAccount.cpp | 21 +++++++++++++++------ src/cpp/controller/HederaId.cpp | 10 +++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 25f3c7245..4a1c45c7c 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -67,18 +67,23 @@ namespace controller { Poco::Tuple result_tuple; int crypto_key_type = encrypted ? model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED : model::table::KEY_TYPE_ED25519_HEDERA_CLEAR; - //id, user_id, account_hedera_id, account_key_id, balance, network_type, updated + int network_type_int = (int)networkType; - select << "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num FROM hedera_accounts as account " - << "JOIN hedera_ids as i ON(i.id = account.account_hedera_id) " + select + << "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num " + << "FROM hedera_accounts as account " + << "JOIN hedera_ids as i ON(i.id = account_hedera_id) " << "JOIN crypto_keys as k ON(k.id = account.account_key_id) " - << "WHERE account.network_type = ? AND k.crypto_key_type_id = ? ORDER BY RAND() LIMIT 1 ", - into(result_tuple), use(networkType), use(crypto_key_type); + << "WHERE account.network_type = ? " + << "AND k.crypto_key_type_id = ? " + << "ORDER BY RAND() LIMIT 1 " + , into(result_tuple), use(network_type_int) , use(crypto_key_type); try { select.executeAsync(); select.wait(); - if (1 == select.rowsExtracted()) { + auto result_count = select.rowsExtracted(); + if (1 == result_count) { auto db = new model::table::HederaAccount( result_tuple.get<1>(), result_tuple.get<2>(), result_tuple.get<3>(), result_tuple.get<4>(), networkType @@ -90,10 +95,14 @@ namespace controller { hedera_account->setHederaId(hedera_id); return hedera_account; } + else if(result_count > 1) { + printf("[HederaAccount::pick] extracted rows not like expected\n"); + } } catch (Poco::Exception& ex) { auto em = ErrorManager::getInstance(); static const char* function_name = "HederaAccount::pick"; + printf("exception: %s\n", ex.displayText().data()); em->addError(new ParamError(function_name, "mysql error: ", ex.displayText())); em->addError(new ParamError(function_name, "network type: ", networkType)); em->addError(new ParamError(function_name, "encrypted: ", (int)encrypted)); diff --git a/src/cpp/controller/HederaId.cpp b/src/cpp/controller/HederaId.cpp index 3b9627c8b..9e39cd84b 100644 --- a/src/cpp/controller/HederaId.cpp +++ b/src/cpp/controller/HederaId.cpp @@ -38,23 +38,23 @@ namespace controller { auto cm = ConnectionManager::getInstance(); auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); model::table::HederaIdTuple result_tuple; + int network_type_int = (int)networkType; Poco::Data::Statement select(session); select << "SELECT h.id, h.shardNum, h.realmNum, h.num FROM hedera_ids as h " << "JOIN hedera_topics as topic ON(topic.topic_hedera_id = h.id) " << "JOIN hedera_accounts as account ON(account.id = topic.auto_renew_account_hedera_id) " << "WHERE topic.group_id = ? AND account.network_type = ?" - , into(result_tuple), use(groupId), use(networkType); + , into(result_tuple), use(groupId), use(network_type_int); try { - /*select.executeAsync(); + select.executeAsync(); select.wait(); - auto result_count = select.rowsExtracted();*/ - auto result_count = select.execute(); + auto result_count = select.rowsExtracted(); if (1 == result_count) { return new HederaId(new model::table::HederaId(result_tuple)); } - else { + else if(result_count > 1) { printf("[HederaId::find] result_count other as expected: %d\n", result_count); } } From 4ece67c057f0f80fe4b686d64e582044bdb4c96d Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Sep 2020 13:22:17 +0200 Subject: [PATCH 079/195] work on hedera task for hedera transactions async --- src/cpp/model/hedera/Transaction.cpp | 2 + src/cpp/model/hedera/Transaction.h | 2 + src/cpp/model/hedera/TransactionReceipt.cpp | 16 ++++++++ src/cpp/model/hedera/TransactionReceipt.h | 23 +++++++++++ src/cpp/model/hedera/TransactionRecord.cpp | 0 src/cpp/model/hedera/TransactionRecord.h | 0 src/cpp/tasks/HederaTask.cpp | 45 +++++++++++++++++++++ src/cpp/tasks/HederaTask.h | 36 ++++++++++++++++- src/cpp/tasks/SigningTransaction.cpp | 6 ++- 9 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/cpp/model/hedera/TransactionReceipt.cpp create mode 100644 src/cpp/model/hedera/TransactionReceipt.h create mode 100644 src/cpp/model/hedera/TransactionRecord.cpp create mode 100644 src/cpp/model/hedera/TransactionRecord.h diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index ab786e44f..779488630 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -58,6 +58,8 @@ namespace model { auto signature_pair = signature_pairs->Mutable(0); auto public_key = keyPairHedera->getPublicKey(); + mTransactionId = transactionBody->getProtoTransactionBody()->transactionid(); + auto sign = keyPairHedera->sign(body_bytes); if (!sign) { printf("[Query::sign] error signing message\n"); diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index fe1bfed51..5938a0f1e 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -29,11 +29,13 @@ namespace model { inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } void resetPointer() { mTransaction = nullptr; } inline TransactionBodyType getType() const { return mType; } + inline proto::TransactionID getTransactionId() const { return mTransactionId; } protected: proto::Transaction* mTransaction; controller::NodeServerConnection mConnection; TransactionBodyType mType; + proto::TransactionID mTransactionId; }; } } diff --git a/src/cpp/model/hedera/TransactionReceipt.cpp b/src/cpp/model/hedera/TransactionReceipt.cpp new file mode 100644 index 000000000..46966814d --- /dev/null +++ b/src/cpp/model/hedera/TransactionReceipt.cpp @@ -0,0 +1,16 @@ +#include "TransactionReceipt.h" + +namespace model { + namespace hedera { + + TransactionReceipt::TransactionReceipt() + { + + } + + TransactionReceipt::~TransactionReceipt() + { + + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionReceipt.h b/src/cpp/model/hedera/TransactionReceipt.h new file mode 100644 index 000000000..ed1036857 --- /dev/null +++ b/src/cpp/model/hedera/TransactionReceipt.h @@ -0,0 +1,23 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H + +#include "../proto/hedera/TransactionReceipt.pb.h" + +namespace model { + namespace hedera { + class TransactionReceipt + { + public: + TransactionReceipt(); + ~TransactionReceipt(); + + inline proto::TransactionReceipt* getProto() { return &mProtoReceipt; } + + protected: + proto::TransactionReceipt mProtoReceipt; + + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionRecord.cpp b/src/cpp/model/hedera/TransactionRecord.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/hedera/TransactionRecord.h b/src/cpp/model/hedera/TransactionRecord.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/tasks/HederaTask.cpp b/src/cpp/tasks/HederaTask.cpp index e69de29bb..9cd152d27 100644 --- a/src/cpp/tasks/HederaTask.cpp +++ b/src/cpp/tasks/HederaTask.cpp @@ -0,0 +1,45 @@ +#include "HederaTask.h" +#include "../lib/DataTypeConverter.h" + +#include "../proto/hedera/TransactionGetReceipt.pb.h" + +HederaTask::HederaTask() + : mTransactionReceipt(nullptr) +{ + +} + +HederaTask::~HederaTask() +{ + if (mTransactionReceipt) { + delete mTransactionReceipt; + mTransactionReceipt = nullptr; + } +} + +bool HederaTask::isTimeout() +{ + std::shared_lock _lock(mWorkingMutex); + auto valid_start = mTransactionID.transactionvalidstart(); + auto poco_timestamp = DataTypeConverter::convertFromProtoTimestamp(valid_start); + auto poco_duration = DataTypeConverter::convertFromProtoDuration(mValidDuration); + return (poco_timestamp + poco_duration) > Poco::Timestamp(); +} + +void HederaTask::setTransactionReceipt(model::hedera::TransactionReceipt* transactionReceipt) +{ + assert(transactionReceipt); + + std::unique_lock _lock(mWorkingMutex); + if (mTransactionReceipt) { + printf("[HederaTask::setTransactionReceipt] warning, receipt already set\n"); + delete mTransactionReceipt; + } + mTransactionReceipt = transactionReceipt; +} + +bool HederaTask::tryQueryReceipt() +{ + proto::TransactionGetReceiptQuery get_receipt_query; + return true; +} \ No newline at end of file diff --git a/src/cpp/tasks/HederaTask.h b/src/cpp/tasks/HederaTask.h index 0c22da226..3576ca7b6 100644 --- a/src/cpp/tasks/HederaTask.h +++ b/src/cpp/tasks/HederaTask.h @@ -2,14 +2,48 @@ #define __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H #include "../model/hedera/TransactionResponse.h" +#include "../model/hedera/TransactionReceipt.h" +#include "../proto/hedera/BasicTypes.pb.h" +#include "../proto/hedera/Duration.pb.h" + +#include "Poco/Timestamp.h" + +#include class HederaTask { public: - inline model::hedera::TransactionResponse* getTransactionResponse() { return &mTransactionResponse; } + + HederaTask(); + ~HederaTask(); + + inline model::hedera::TransactionResponse* getTransactionResponse() { std::shared_lock _lock(mWorkingMutex); return &mTransactionResponse; } + inline void setTransactionId(const proto::TransactionID& transactionId) { std::unique_lock _lock(mWorkingMutex); mTransactionID = transactionId; } + inline void setValidDuration(const proto::Duration& validDuration) { std::unique_lock _lock(mWorkingMutex); mValidDuration = validDuration; } + //! \param transactionReceipt take ownership and call delete if done + void setTransactionReceipt(model::hedera::TransactionReceipt* transactionReceipt); + + inline const proto::TransactionID& getTransactionId() const { std::shared_lock _lock(mWorkingMutex); return mTransactionID; } + inline const proto::Duration& getDuration() const { std::shared_lock _lock(mWorkingMutex); return mValidDuration; } + inline const model::hedera::TransactionReceipt* getTransactionReceipt() const{ std::shared_lock _lock(mWorkingMutex); return mTransactionReceipt; } + + //! \ brief return true if transactionValidStart + validDuration > now + bool isTimeout(); + + bool tryQueryReceipt(); + protected: model::hedera::TransactionResponse mTransactionResponse; + model::hedera::TransactionReceipt* mTransactionReceipt; + + proto::TransactionID mTransactionID; + proto::Duration mValidDuration; + + // last time checked if transaction receipt is available + Poco::Timestamp mLastCheck; + + mutable std::shared_mutex mWorkingMutex; }; #endif //__GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H \ No newline at end of file diff --git a/src/cpp/tasks/SigningTransaction.cpp b/src/cpp/tasks/SigningTransaction.cpp index 297d2ca1d..b05d84963 100644 --- a/src/cpp/tasks/SigningTransaction.cpp +++ b/src/cpp/tasks/SigningTransaction.cpp @@ -1,5 +1,8 @@ +#include + #include "SigningTransaction.h" + #include #include "../SingletonManager/ErrorManager.h" @@ -184,7 +187,8 @@ int SigningTransaction::run() { } else { auto hedera_precheck_code_string = hedera_task.getTransactionResponse()->getPrecheckCodeString(); - printf("hedera response: %s\n", hedera_precheck_code_string.data()); + auto cost = hedera_task.getTransactionResponse()->getCost(); + printf("hedera response: %s, cost: %" PRIu64 "\n", hedera_precheck_code_string.data(), cost); } //model::hedera::TransactionBody hedera_transaction_body() } From 7bc02f4e63acb9ab8229caf2d8c99849f56a93db Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Sep 2020 13:25:15 +0200 Subject: [PATCH 080/195] prepare for hedera get topic info query --- .../hedera/ConsensusGetTopicInfoResponse.cpp | 15 ++++++++++ .../hedera/ConsensusGetTopicInfoResponse.h | 22 ++++++++++++++ src/cpp/model/hedera/Query.cpp | 25 ++++++++++++++++ src/cpp/model/hedera/Query.h | 2 ++ src/cpp/model/hedera/QueryHeader.cpp | 16 ++++++++++ src/cpp/model/hedera/QueryHeader.h | 25 ++++++++++++++++ src/cpp/model/hedera/Response.cpp | 15 ++++++++++ src/cpp/model/hedera/Response.h | 4 +++ src/cpp/model/hedera/TransactionBody.cpp | 30 ++++++++++++++++++- src/cpp/model/hedera/TransactionBody.h | 1 + 10 files changed, 154 insertions(+), 1 deletion(-) diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp index e69de29bb..f99d82934 100644 --- a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp +++ b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.cpp @@ -0,0 +1,15 @@ +#include "ConsensusGetTopicInfoResponse.h" + +namespace model { + namespace hedera { + ConsensusGetTopicInfoResponse::ConsensusGetTopicInfoResponse() + { + + } + + ConsensusGetTopicInfoResponse::~ConsensusGetTopicInfoResponse() + { + + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h index e69de29bb..63b837101 100644 --- a/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h +++ b/src/cpp/model/hedera/ConsensusGetTopicInfoResponse.h @@ -0,0 +1,22 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H + +#include "../proto/hedera/ConsensusGetTopicInfo.pb.h" + +namespace model +{ + namespace hedera + { + class ConsensusGetTopicInfoResponse + { + public: + ConsensusGetTopicInfoResponse(); + ~ConsensusGetTopicInfoResponse(); + + protected: + proto::ConsensusGetTopicInfoResponse mProto; + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index 11a8eb735..c478a96ff 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -48,6 +48,29 @@ namespace model { return query; } + Query* Query::getTopicInfo(Poco::AutoPtr topicId, Poco::AutoPtr payerAccountId, const controller::NodeServerConnection& connection) + { + assert(!topicId.isNull() && topicId->getModel()); + assert(!payerAccountId.isNull() && payerAccountId->getModel()); + + auto query = new Query; + auto get_topic_info = query->mQueryProto.mutable_consensusgettopicinfo(); + topicId->copyToProtoTopicId(get_topic_info->mutable_topicid()); + + auto query_header = get_topic_info->mutable_header(); + query_header->set_responsetype(proto::ANSWER_ONLY); + + query->mTransactionBody = new TransactionBody(payerAccountId, connection); + CryptoTransferTransaction crypto_transaction; + // 0.002809 Hashbars + // fee from https://www.hedera.com/fees + crypto_transaction.addSender(payerAccountId, -2809); + crypto_transaction.addReceiver(connection.hederaId, 2809); + query->mTransactionBody->setCryptoTransfer(crypto_transaction); + + return query; + } + bool Query::sign(std::unique_ptr keyPairHedera) { Transaction transaction; @@ -73,5 +96,7 @@ namespace model { auto query_header = get_account_balance->mutable_header(); return query_header->responsetype(); } + + } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index 376528314..5c633e66c 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -22,10 +22,12 @@ namespace model { public: ~Query(); static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); + static Query* getTopicInfo(Poco::AutoPtr topicId, Poco::AutoPtr payerAccountId, const controller::NodeServerConnection& connection); bool sign(std::unique_ptr keyPairHedera); void setResponseType(proto::ResponseType type); proto::ResponseType getResponseType(); + inline bool setTransactionFee(Poco::UInt64 fee) { return mTransactionBody->updateCryptoTransferAmount(fee);} inline const proto::Query* getProtoQuery() const { return &mQueryProto; } inline std::string getConnectionString() const { return mTransactionBody->getConnectionString(); } diff --git a/src/cpp/model/hedera/QueryHeader.cpp b/src/cpp/model/hedera/QueryHeader.cpp index e69de29bb..c622841ec 100644 --- a/src/cpp/model/hedera/QueryHeader.cpp +++ b/src/cpp/model/hedera/QueryHeader.cpp @@ -0,0 +1,16 @@ +#include "QueryHeader.h" + +namespace model { + namespace hedera { + QueryHeader::QueryHeader(Transaction* paymentTransaction) + { + mProtoQueryHeader.set_responsetype(proto::ANSWER_ONLY); + } + + QueryHeader::~QueryHeader() + { + + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/QueryHeader.h b/src/cpp/model/hedera/QueryHeader.h index e69de29bb..47261e24a 100644 --- a/src/cpp/model/hedera/QueryHeader.h +++ b/src/cpp/model/hedera/QueryHeader.h @@ -0,0 +1,25 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H +#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H + +#include "../proto/hedera/QueryHeader.pb.h" +#include "Transaction.h" + +namespace model { + namespace hedera { + class QueryHeader + { + public: + QueryHeader(Transaction* paymentTransaction); + ~QueryHeader(); + + void setResponseType(proto::ResponseType type) { mProtoQueryHeader.set_responsetype(type); }; + proto::ResponseType getResponseType() const { return mProtoQueryHeader.responsetype(); } + + protected: + proto::QueryHeader mProtoQueryHeader; + + }; + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp index a39c5364e..d0a88ad94 100644 --- a/src/cpp/model/hedera/Response.cpp +++ b/src/cpp/model/hedera/Response.cpp @@ -20,6 +20,21 @@ namespace model { return 0; } + Poco::UInt64 Response::getQueryCost() + { + proto::ResponseHeader* response_header = nullptr; + if (mResponseProto.has_consensusgettopicinfo()) { + response_header = mResponseProto.mutable_consensusgettopicinfo()->mutable_header(); + } + else if (mResponseProto.has_cryptogetaccountbalance()) { + response_header = mResponseProto.mutable_cryptogetaccountbalance()->mutable_header(); + } + if (response_header) { + return response_header->cost(); + } + return 0; + } + proto::ResponseCodeEnum Response::getResponseCode() { if (isCryptoGetAccountBalanceResponse()) { diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h index 779f5e982..89599b8c4 100644 --- a/src/cpp/model/hedera/Response.h +++ b/src/cpp/model/hedera/Response.h @@ -11,6 +11,7 @@ */ #include "../../proto/hedera/Response.pb.h" +#include "ConsensusGetTopicInfoResponse.h" #include "Poco/Types.h" namespace model { @@ -23,9 +24,12 @@ namespace model { inline proto::Response* getResponsePtr() { return &mResponseProto; } Poco::UInt64 getAccountBalance(); + Poco::UInt64 getQueryCost(); proto::ResponseCodeEnum getResponseCode(); + inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); } + inline bool isConsensusGetTopicInfoResponse() { return mResponseProto.has_consensusgettopicinfo(); } protected: proto::Response mResponseProto; diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index ea44915a8..4ecae0fb9 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -8,7 +8,7 @@ namespace model { connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); auto transaction_id = mTransactionBody.mutable_transactionid(); operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid()); - mTransactionBody.set_transactionfee(10000); + mTransactionBody.set_transactionfee(1000000); auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration(); transaction_valid_duration->set_seconds(120); @@ -36,6 +36,34 @@ namespace model { return false; } + bool TransactionBody::updateCryptoTransferAmount(Poco::UInt64 newAmount) + { + assert(mHasBody); + + if (!mTransactionBody.has_cryptotransfer()) { + printf("[TransactionBody::updateCryptoTransferAmount] hasn't crypto transfer\n"); + return false; + } + + auto crypto_transfer = mTransactionBody.mutable_cryptotransfer(); + auto transfers = crypto_transfer->mutable_transfers(); + if (transfers->accountamounts_size() != 2) { + printf("[TransactionBody::updateCryptoTransferAmount] structure not like expected, transfers has %d accountamounts\n", transfers->accountamounts_size()); + return false; + } + proto::AccountAmount* account_amounts[] = { transfers->mutable_accountamounts(0), transfers->mutable_accountamounts(1) }; + for (int i = 0; i < 2; i++) { + if (account_amounts[i]->amount() > 0) { + account_amounts[i]->set_amount(newAmount); + } + else if (account_amounts[i]->amount() < 0) { + account_amounts[i]->set_amount(-newAmount); + } + } + return true; + + } + bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction) { if (mHasBody) { diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 9a5406af7..c05f419ff 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -40,6 +40,7 @@ namespace model { void setFee(Poco::UInt64 fee); bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + bool updateCryptoTransferAmount(Poco::UInt64 newAmount); bool setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction); bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction); bool setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction); From a41ea1a6ae94de8841c3b85f27e419926359cdfc Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Sep 2020 13:26:05 +0200 Subject: [PATCH 081/195] update Hedera Topics Page to show existing topics --- skeema/gradido_login/hedera_topics.sql | 4 +- .../HTTPInterface/AdminHederaAccountPage.cpp | 68 ++--- src/cpp/HTTPInterface/AdminTopicPage.cpp | 245 ++++++++++++++---- src/cpp/controller/HederaAccount.cpp | 24 +- src/cpp/controller/HederaAccount.h | 6 +- src/cpp/controller/HederaRequest.cpp | 38 ++- src/cpp/controller/HederaTopic.cpp | 34 ++- src/cpp/controller/HederaTopic.h | 9 +- src/cpp/lib/DataTypeConverter.cpp | 11 + src/cpp/lib/DataTypeConverter.h | 6 + src/cpp/model/table/HederaAccount.cpp | 20 +- src/cpp/model/table/HederaAccount.h | 1 + src/cpp/model/table/HederaTopic.cpp | 37 ++- src/cpp/model/table/HederaTopic.h | 10 +- src/cpp/model/table/ModelBase.cpp | 24 ++ src/cpp/model/table/ModelBase.h | 26 +- src/cpsp/adminHederaAccount.cpsp | 18 +- src/cpsp/adminTopic.cpsp | 55 +++- 18 files changed, 500 insertions(+), 136 deletions(-) diff --git a/skeema/gradido_login/hedera_topics.sql b/skeema/gradido_login/hedera_topics.sql index b9adaefc2..8bf279f3b 100644 --- a/skeema/gradido_login/hedera_topics.sql +++ b/skeema/gradido_login/hedera_topics.sql @@ -7,9 +7,9 @@ CREATE TABLE `hedera_topics` ( `group_id` int unsigned NOT NULL, `admin_key_id` int unsigned DEFAULT NULL, `submit_key_id` int unsigned DEFAULT NULL, - `current_timeout` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', + `current_timeout` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00', `sequence_number` bigint unsigned DEFAULT '0', - `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `topic_hedera_id` (`topic_hedera_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 5ff4f7218..4bcf9b614 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -349,8 +349,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; #line 266 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - responseStream << ( hedera_account_model->getBalanceDouble() ); - responseStream << " hbar
    \n"; + responseStream << ( hedera_account_model->getBalanceString() ); + responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; #line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); @@ -366,27 +366,29 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request #line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" - if(changeEncryption != "") { responseStream << "\n"; - responseStream << "\t\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" + responseStream << "\t\t\t\t\t\t\t\tChange Encryption\n"; + responseStream << "\t\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 278 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; + responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 279 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -395,7 +397,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; @@ -411,21 +413,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; @@ -436,46 +438,46 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\n"; @@ -506,7 +508,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request // end include footer.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\t\t\n"; responseStream << "\t "; -#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" +#line 222 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" } else if(state == PAGE_ASK_PASSPHRASE) { responseStream << "\n"; responseStream << "\t \n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "
    \n"; - responseStream << "\t

    Login Server in Entwicklung

    \n"; - responseStream << "\t

    Alpha "; -#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" - responseStream << ( ServerConfig::g_versionString ); - responseStream << "

    \n"; - responseStream << "
    \n"; - // end include header_old.cpsp - responseStream << "\n"; - responseStream << "
    \n"; - responseStream << "\t

    Einen neuen Account anlegen

    \n"; - responseStream << "\t"; -#line 45 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - responseStream << ( getErrorsHtml() ); - responseStream << "\n"; - responseStream << "\t"; -#line 46 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - if(!form.empty() && userReturned) { responseStream << "\n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t\tDeine Anmeldung wird verarbeitet und es wird dir eine E-Mail zugeschickt. \n"; - responseStream << "\t\t\t\tWenn sie da ist, befolge ihren Anweisungen. \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t"; -#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - } else { responseStream << "\n"; - responseStream << "\t
    \n"; - responseStream << "\t\t\n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\tAccount anlegen\n"; - responseStream << "\t\t\t

    Bitte gebe deine Daten um einen Account anzulegen

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t

    \n"; - responseStream << "\t\t
    \n"; - responseStream << "\t\t\n"; - responseStream << "\t\t\n"; - responseStream << "\t
    \n"; - responseStream << "\t"; -#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\register.cpsp" - } responseStream << "\n"; - responseStream << "
    \n"; - // begin include footer.cpsp - responseStream << "
    \n"; - responseStream << "

    Copyright © Gradido 2020

    \n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << " "; -#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" - responseStream << ( mTimeProfiler.string() ); - responseStream << "\n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "

    Login Server in Entwicklung

    \n"; - responseStream << "

    Alpha "; -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" - responseStream << ( ServerConfig::g_versionString ); - responseStream << "

    \n"; - responseStream << "
    \n"; - responseStream << "
    \n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << ""; - // end include footer.cpsp - responseStream << "\n"; - if (_compressResponse) _gzipStream.close(); -} diff --git a/src/cpp/HTTPInterface/RegisterPage.h b/src/cpp/HTTPInterface/RegisterPage.h deleted file mode 100644 index 7dc16970a..000000000 --- a/src/cpp/HTTPInterface/RegisterPage.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef RegisterPage_INCLUDED -#define RegisterPage_INCLUDED - - -#include "Poco/Net/HTTPRequestHandler.h" - - -#include "PageRequestMessagedHandler.h" - - -class RegisterPage: public PageRequestMessagedHandler -{ -public: - void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); -}; - - -#endif // RegisterPage_INCLUDED diff --git a/src/cpp/HTTPInterface/SaveKeysPage.cpp b/src/cpp/HTTPInterface/SaveKeysPage.cpp index 12064f812..3d8d79b67 100644 --- a/src/cpp/HTTPInterface/SaveKeysPage.cpp +++ b/src/cpp/HTTPInterface/SaveKeysPage.cpp @@ -40,7 +40,8 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne const char* pageName = "Daten auf Server speichern?"; bool hasErrors = mSession->errorCount() > 0; // crypto key only in memory, if user has tipped in his passwort in this session - bool hasPassword = mSession->getUser()->hasCryptoKey(); + auto user = mSession->getNewUser(); + bool hasPassword = user->getModel()->hasPrivateKeyEncrypted(); PageState state = PAGE_ASK; auto uri_start = ServerConfig::g_php_serverPath;//request.serverParams().getServerName(); @@ -161,11 +162,11 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "
    \n"; responseStream << "\t

    Daten speichern

    \n"; responseStream << "\t"; -#line 75 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 76 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\t"; -#line 76 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 77 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" if(state == PAGE_ASK) { responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; @@ -180,7 +181,7 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t

    \n"; responseStream << "\t\t\t"; -#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" if(!hasPassword) { responseStream << "\n"; responseStream << "\t\t\t\t

    Ich brauche nochmal dein Passwort wenn du dich für ja entscheidest.

    \n"; responseStream << "\t\t\t\t

    \n"; @@ -188,7 +189,7 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t

    \n"; responseStream << "\t\t\t"; -#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 96 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    \n"; responseStream << "\t\t\t\t\n"; @@ -213,15 +214,15 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\n"; responseStream << "\t

    \n"; responseStream << "\t"; -#line 118 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 119 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } else if(state == PAGE_SHOW_PUBKEY) { responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t

    "; -#line 120 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( gettext("Daten gespeichert!") ); responseStream << "

    \n"; responseStream << "\t\t\t

    "; -#line 121 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 122 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( gettext("Deine Daten wurden verschlüsselt und gespeichert.") ); responseStream << "

    \n"; responseStream << "\t\t\t\n"; @@ -229,27 +230,27 @@ void SaveKeysPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne responseStream << "\t\t\t\n"; responseStream << "\t\t\tZurück zur Startseite\n"; responseStream << "\t\t
    \n"; responseStream << "\t"; -#line 130 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 131 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } else if(state == PAGE_ERROR) { responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t

    Ein Fehler trat auf, bitte versuche es erneut oder wende dich an den Server-Admin

    \n"; responseStream << "\t\t\t"; -#line 133 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 134 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" responseStream << ( mSession->getSessionStateString() ); responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t"; -#line 135 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" +#line 136 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\saveKeys.cpsp" } responseStream << "\n"; responseStream << "
    \n"; // begin include footer.cpsp diff --git a/src/cpp/HTTPInterface/TranslatePassphrase.cpp b/src/cpp/HTTPInterface/TranslatePassphrase.cpp index 15ddb3733..61e99c223 100644 --- a/src/cpp/HTTPInterface/TranslatePassphrase.cpp +++ b/src/cpp/HTTPInterface/TranslatePassphrase.cpp @@ -5,11 +5,11 @@ #include "Poco/DeflatingStream.h" -#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 7 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" -#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 1 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header.cpsp" #include "../ServerConfig.h" @@ -28,7 +28,7 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 11 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" chooseLanguage(request); // variable needed for flags @@ -50,16 +50,17 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P { inputPassphrase = form.get("inputPassphrase", ""); - auto localPassphrase = KeyPair::filterPassphrase(inputPassphrase); + auto localPassphrase = Passphrase::filter(inputPassphrase); auto btnGenerate = form.get("btnGenerate", ""); if("" != btnGenerate) { - mSession->generatePassphrase(); - localPassphrase = mSession->getOldPassphrase(); + auto passphrase_gen = Passphrase::generate(wordSource); + + localPassphrase = passphrase_gen->getString(); inputPassphrase = localPassphrase; } - - if(localPassphrase != "" && !User::validatePassphrase(localPassphrase, &wordSource)) { + auto passphrase_object = Passphrase::create(localPassphrase, wordSource); + if(localPassphrase != "" && passphrase_object.isNull() || !passphrase_object->checkIfValid()) { addError(new Error( gettext("Fehler"), gettext("Diese Passphrase ist ungültig, bitte überprüfen oder neu generieren (lassen).") @@ -70,12 +71,13 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P } else { targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]; } - passphrase = KeyPair::passphraseTransform(localPassphrase, wordSource, targetSource); + auto transformed_passphrase_obj = passphrase_object->transform(targetSource); + passphrase = transformed_passphrase_obj->getString(); } } -#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 3 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header.cpsp" bool withMaterialIcons = false; std::ostream& _responseStream = response.send(); @@ -91,20 +93,20 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\n"; responseStream << "\n"; responseStream << "Gradido Login Server: "; -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 11 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header.cpsp" responseStream << ( pageName ); responseStream << "\n"; responseStream << "\n"; -#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 13 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header.cpsp" if(withMaterialIcons) { responseStream << "\n"; responseStream << "\n"; -#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp" +#line 15 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header.cpsp" } responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; @@ -112,20 +114,20 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "
    \n"; responseStream << "
    \n"; responseStream << " \n"; responseStream << " \n"; responseStream << " \n"; responseStream << " \n"; responseStream << " \"logo\"\n"; responseStream << " \n"; @@ -137,20 +139,20 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "
    \n"; responseStream << "
    \n"; responseStream << " \n"; responseStream << " \n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t \n"; responseStream << "\t\t\t\t\"logo\"\n"; responseStream << "\t\t\t\n"; @@ -162,7 +164,7 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "
    \n"; responseStream << "
    \n"; responseStream << " "; -#line 18 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login_header.cpsp" +#line 18 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\login_header.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -172,22 +174,22 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "
    \n"; responseStream << "
    \n"; responseStream << "\t\n"; responseStream << "\t\n"; @@ -197,7 +199,7 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t

    "; -#line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 61 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Passphrase umwandeln") ); responseStream << "

    \n"; responseStream << "
    \n"; @@ -208,57 +210,57 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t
    "; -#line 67 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 69 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Was zu tun ist:") ); responseStream << "
    \n"; responseStream << "\t\t

    "; -#line 68 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 70 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Kopiere/schreibe deine Passphrase in die Textbox und du bekommst sie in die jeweils andere Sprache umgewandelt.") ); responseStream << "

    \n"; responseStream << "\t\t

    "; -#line 69 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 71 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( gettext("Du kannst mit beiden Varianten dein Konto wiederherstellen oder dein Passwort ändern.") ); responseStream << "

    \n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t \n"; responseStream << "\t\t "; -#line 78 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 80 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" if(model::table::ROLE_ADMIN == role) { responseStream << "\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t "; -#line 80 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 82 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" } responseStream << "\n"; responseStream << "\t\t\n"; responseStream << "\t
    \n"; responseStream << "\t "; -#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 85 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" if(passphrase != "") { responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t
    Umgewandelte Passphrase:
    \n"; responseStream << "\t\t\t\t

    "; -#line 87 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 89 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" responseStream << ( passphrase ); responseStream << "

    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t "; -#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\translatePassphrase.cpsp" +#line 92 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\translatePassphrase.cpsp" } responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "\t
    \n"; @@ -287,7 +289,7 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "
    \n"; responseStream << "
    \n"; responseStream << " "; -#line 23 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer_ripple.cpsp" +#line 23 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\footer_ripple.cpsp" responseStream << ( mTimeProfiler.string() ); responseStream << "\n"; responseStream << "
    \n"; @@ -303,7 +305,7 @@ void TranslatePassphrase::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << " \n"; responseStream << " \n"; responseStream << " \n"; responseStream << " \n"; diff --git a/src/cpp/HTTPInterface/UserUpdateGroupPage.cpp b/src/cpp/HTTPInterface/UserUpdateGroupPage.cpp new file mode 100644 index 000000000..f41928116 --- /dev/null +++ b/src/cpp/HTTPInterface/UserUpdateGroupPage.cpp @@ -0,0 +1,209 @@ +#include "UserUpdateGroupPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + + +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" + +enum PageState { + PAGE_STATE_OVERVIEW, + PAGE_STATE_REQUEST_IS_RUNNING +}; + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +UserUpdateGroupPage::UserUpdateGroupPage(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void UserUpdateGroupPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 17 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + + const char* pageName = gettext("Gruppe wählen"); + auto user = mSession->getNewUser(); + auto sm = SessionManager::getInstance(); + PageState state = PAGE_STATE_OVERVIEW; + + if(!form.empty()) { + } + + auto groups = controller::Group::listAll(); + + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t
    "; + // end include header_large.cpsp + responseStream << "\n"; +#line 30 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "\t"; +#line 32 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + if(PAGE_STATE_OVERVIEW == state ) { responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "

    "; +#line 34 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Gruppe wählen") ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "\t

    "; +#line 36 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Bitte wähle die Gruppe/Gemeinschaft aus, zu der du gehörst.") ); + responseStream << "

    \n"; + responseStream << "\t

    "; +#line 37 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Du bekommst eine Bestätigungsmail, nachdem dein Beitritt bestätigt wurde.") ); + responseStream << "

    \n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t\t
    "; +#line 41 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Auswahl") ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t
    Name
    \n"; + responseStream << "\t\t\t\t
    Alias
    \n"; + responseStream << "\t\t\t\t
    Url
    \n"; + responseStream << "\t\t\t\t
    "; +#line 45 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( gettext("Description") ); + responseStream << "
    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 47 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t
    getID()); + responseStream << "\" />
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 51 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getName() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 52 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getAlias() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getUrl() ); + responseStream << "
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 54 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + responseStream << ( group_model->getDescription()); + responseStream << "
    \n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t"; +#line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t
    \n"; + responseStream << "\t"; +#line 60 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\userUpdateGroup.cpsp" + } responseStream << "\n"; + responseStream << "
    \n"; + // begin include footer.cpsp + responseStream << "
    \n"; + responseStream << "

    Copyright © Gradido 2020

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "

    Login Server in Entwicklung

    \n"; + responseStream << "

    Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

    \n"; + responseStream << "
    \n"; + responseStream << "
    \n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/UserUpdateGroupPage.h b/src/cpp/HTTPInterface/UserUpdateGroupPage.h new file mode 100644 index 000000000..5b1e9a7d1 --- /dev/null +++ b/src/cpp/HTTPInterface/UserUpdateGroupPage.h @@ -0,0 +1,20 @@ +#ifndef UserUpdateGroupPage_INCLUDED +#define UserUpdateGroupPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class UserUpdateGroupPage: public SessionHTTPRequestHandler +{ +public: + UserUpdateGroupPage(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // UserUpdateGroupPage_INCLUDED diff --git a/src/cpp/ImportantTests.cpp b/src/cpp/ImportantTests.cpp index d321bab5f..33c7d0f26 100644 --- a/src/cpp/ImportantTests.cpp +++ b/src/cpp/ImportantTests.cpp @@ -2,7 +2,7 @@ #include #include "ServerConfig.h" -#include "Crypto/KeyPair.h" +//#include "Crypto/KeyPair.h" #include "Crypto/KeyPairEd25519.h" #include "lib/DataTypeConverter.h" @@ -38,27 +38,36 @@ namespace ImportantTests { // test old key pair implementation - KeyPair keys; + //KeyPair keys; bool errorsOccured = false; - std::string filtered_1_de = KeyPair::filterPassphrase(passphrase_1_de); - keys.generateFromPassphrase(filtered_1_de.data(), de_words); - if (keys.getPubkeyHex() != passphrase_1_pubkey_hex) { + std::string filtered_1_de = Passphrase::filter(passphrase_1_de); + KeyPairEd25519* keys = nullptr; + keys = KeyPairEd25519::create(Passphrase::create(filtered_1_de, de_words)); + std::string public_key_hex = keys->getPublicKeyHex(); + + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_1_pubkey_hex) { printf("1 de incorrect\n"); errorsOccured = true; } - keys.generateFromPassphrase(passphrase_1_en.data(), en_words); - if (keys.getPubkeyHex() != passphrase_1_pubkey_hex) { + delete keys; + keys = KeyPairEd25519::create(Passphrase::create(passphrase_1_en, en_words)); + public_key_hex = keys->getPublicKeyHex(); + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_1_pubkey_hex) { printf("1 en incorrect\n"); errorsOccured = true; } - std::string filtered_2_de = KeyPair::filterPassphrase(passphrase_2_de); - keys.generateFromPassphrase(filtered_2_de.data(), de_words); - if (keys.getPubkeyHex() != passphrase_2_pubkey_hex) { + std::string filtered_2_de = Passphrase::filter(passphrase_2_de); + delete keys; + keys = KeyPairEd25519::create(Passphrase::create(filtered_2_de, de_words)); + public_key_hex = keys->getPublicKeyHex(); + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_2_pubkey_hex) { printf("2 de incorrect\n"); errorsOccured = true; } - keys.generateFromPassphrase(passphrase_2_en.data(), en_words); - if (keys.getPubkeyHex() != passphrase_2_pubkey_hex) { + delete keys; + keys = KeyPairEd25519::create(Passphrase::create(passphrase_2_en, en_words)); + public_key_hex = keys->getPublicKeyHex(); + if (std::string(public_key_hex.data(), public_key_hex.size() - 1) != passphrase_2_pubkey_hex) { printf("2 en incorrect\n"); errorsOccured = true; } diff --git a/src/cpp/JSONInterface/JsonCreateUser.cpp b/src/cpp/JSONInterface/JsonCreateUser.cpp index 6b5ecf33d..c7d93568e 100644 --- a/src/cpp/JSONInterface/JsonCreateUser.cpp +++ b/src/cpp/JSONInterface/JsonCreateUser.cpp @@ -1,108 +1,113 @@ -#include "JsonCreateUser.h" - -#include "../model/email/Email.h" -#include "../controller/User.h" -#include "../controller/EmailVerificationCode.h" - -#include "../SingletonManager/EmailManager.h" -#include "../SingletonManager/SessionManager.h" - -#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h" - -Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) -{ - std::string email; - std::string first_name; - std::string last_name; - std::string password; - bool login_after_register = false; - int emailType; - auto em = EmailManager::getInstance(); - auto sm = SessionManager::getInstance(); - - // if is json object - if (params.type() == typeid(Poco::JSON::Object::Ptr)) { - Poco::JSON::Object::Ptr paramJsonObject = params.extract(); - /// Throws a RangeException if the value does not fit - /// into the result variable. - /// Throws a NotImplementedException if conversion is - /// not available for the given type. - /// Throws InvalidAccessException if Var is empty. - try { - paramJsonObject->get("email").convert(email); - paramJsonObject->get("first_name").convert(first_name); - paramJsonObject->get("last_name").convert(last_name); - paramJsonObject->get("emailType").convert(emailType); - - if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) { - paramJsonObject->get("password").convert(password); - } - if (!paramJsonObject->isNull("login_after_register")) { - paramJsonObject->get("login_after_register").convert(login_after_register); - } - } - catch (Poco::Exception& ex) { - return stateError("json exception", ex.displayText()); - } - } - else { - return stateError("parameter format unknown"); - } - - auto user = controller::User::create(); - if (user->load(email) > 0) { - return customStateError("exist", "user already exist"); - } - - if (password.size()) { - ErrorList errors; - if (!sm->checkPwdValidation(password, &errors)) { - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", "error"); - result->set("msg", errors.getLastError()->getString(false)); - if (errors.errorCount()) { - result->set("details", errors.getLastError()->getString(false)); - } - return result; - } - } - - // create user - user = controller::User::create(email, first_name, last_name); - auto userModel = user->getModel(); - Session* session = nullptr; - - if (!userModel->insertIntoDB(true)) { - userModel->sendErrorsAsEmail(); - return stateError("insert user failed"); - } - if (password.size()) { - session = sm->getNewSession(); - session->setUser(user); - session->generateKeys(true, true); - session->setClientIp(mClientIP); - - // calculate encryption key, could need some time, will save encrypted privkey to db - UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(user, password); - create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); - } - - auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); - auto emailOptInModel = emailOptIn->getModel(); - if (!emailOptInModel->insertIntoDB(false)) { - emailOptInModel->sendErrorsAsEmail(); - return stateError("insert emailOptIn failed"); - } - - em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); - - if (login_after_register && session) { - Poco::JSON::Object* result = stateSuccess(); - - result->set("session_id", session->getHandle()); - return result; - } - - return stateSuccess(); - +#include "JsonCreateUser.h" + +#include "../model/email/Email.h" +#include "../controller/User.h" +#include "../controller/EmailVerificationCode.h" + +#include "../SingletonManager/EmailManager.h" +#include "../SingletonManager/SessionManager.h" + +#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h" + +Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) +{ + std::string email; + std::string first_name; + std::string last_name; + std::string password; + bool login_after_register = false; + int emailType; + int group_id; + auto em = EmailManager::getInstance(); + auto sm = SessionManager::getInstance(); + + // if is json object + if (params.type() == typeid(Poco::JSON::Object::Ptr)) { + Poco::JSON::Object::Ptr paramJsonObject = params.extract(); + /// Throws a RangeException if the value does not fit + /// into the result variable. + /// Throws a NotImplementedException if conversion is + /// not available for the given type. + /// Throws InvalidAccessException if Var is empty. + try { + paramJsonObject->get("email").convert(email); + paramJsonObject->get("first_name").convert(first_name); + paramJsonObject->get("last_name").convert(last_name); + paramJsonObject->get("emailType").convert(emailType); + paramJsonObject->get("group_id").convert(group_id); + + if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) { + paramJsonObject->get("password").convert(password); + } + if (!paramJsonObject->isNull("login_after_register")) { + paramJsonObject->get("login_after_register").convert(login_after_register); + } + } + catch (Poco::Exception& ex) { + return stateError("json exception", ex.displayText()); + } + } + else { + return stateError("parameter format unknown"); + } + + auto user = controller::User::create(); + if (user->load(email) > 0) { + // return customStateError("exist", "user already exist"); + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "exist"); + result->set("msg", "user already exist"); + return result; + } + + if (password.size()) { + ErrorList errors; + if (!sm->checkPwdValidation(password, &errors)) { + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "error"); + result->set("msg", errors.getLastError()->getString(false)); + if (errors.errorCount()) { + result->set("details", errors.getLastError()->getString(false)); + } + return result; + } + } + + // create user + user = controller::User::create(email, first_name, last_name, group_id); + auto userModel = user->getModel(); + Session* session = nullptr; + + if (!userModel->insertIntoDB(true)) { + userModel->sendErrorsAsEmail(); + return stateError("insert user failed"); + } + if (password.size()) { + session = sm->getNewSession(); + session->setUser(user); + session->generateKeys(true, true); + session->setClientIp(mClientIP); + + // calculate encryption key, could need some time, will save encrypted privkey to db + UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(user, password); + create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); + } + + auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); + auto emailOptInModel = emailOptIn->getModel(); + if (!emailOptInModel->insertIntoDB(false)) { + emailOptInModel->sendErrorsAsEmail(); + return stateError("insert emailOptIn failed"); + } + + em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); + + if (login_after_register && session) { + Poco::JSON::Object* result = stateSuccess(); + + result->set("session_id", session->getHandle()); + return result; + } + + return stateSuccess(); } \ No newline at end of file diff --git a/src/cpp/JSONInterface/JsonTransaction.cpp b/src/cpp/JSONInterface/JsonTransaction.cpp index 62f001469..99fa5a6f6 100644 --- a/src/cpp/JSONInterface/JsonTransaction.cpp +++ b/src/cpp/JSONInterface/JsonTransaction.cpp @@ -1,175 +1,175 @@ -#include "JsonTransaction.h" -#include "Poco/URI.h" -#include "Poco/Dynamic/Struct.h" - -#include "../SingletonManager/SessionManager.h" -#include "../ServerConfig.h" - -Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params) -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - int session_id = 0; - - // if is json object - if (params.type() == typeid(Poco::JSON::Object::Ptr)) { - Poco::JSON::Object::Ptr paramJsonObject = params.extract(); - - try { - /// Throws a RangeException if the value does not fit - /// into the result variable. - /// Throws a NotImplementedException if conversion is - /// not available for the given type. - /// Throws InvalidAccessException if Var is empty. - paramJsonObject->get("session_id").convert(session_id); - auto sm = SessionManager::getInstance(); - if (session_id != 0) { - auto session = sm->getSession(session_id); - if (!session) { - result->set("state", "error"); - result->set("msg", "session not found"); - return result; - } - - int balance = 0; - - if (!paramJsonObject->isNull("balance")) { - paramJsonObject->get("balance").convert(balance); - if (balance) { - auto u = session->getUser(); - if (u) { - u->setBalance(balance); - } - auto nu = session->getNewUser(); - if (!nu.isNull()) { - nu->setBalance(balance); - } - } - } - - std::string transactionBase64String; - Poco::Dynamic::Var transaction_base64 = paramJsonObject->get("transaction_base64"); - bool auto_sign = false; - auto auto_sign_json = paramJsonObject->get("auto_sign"); - if (!auto_sign_json.isEmpty()) { - auto_sign_json.convert(auto_sign); - } - - if (transaction_base64.isString()) { - paramJsonObject->get("transaction_base64").convert(transactionBase64String); - - if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) { - if (auto_sign) { - auto errorJson = session->getErrorsArray(); - result->set("state", "error"); - result->set("msg", "error processing transaction"); - result->set("details", errorJson); - return result; - } - auto lastError = session->getLastError(); - if (lastError) delete lastError; - result->set("state", "error"); - result->set("msg", "already enlisted"); - return result; - } - - } else { - Poco::DynamicStruct ds = *paramJsonObject; - int alreadyEnlisted = 0; - - for (int i = 0; i < ds["transaction_base64"].size(); i++) { - ds["transaction_base64"][i].convert(transactionBase64String); - if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) { - auto lastError = session->getLastError(); - if (lastError) delete lastError; - alreadyEnlisted++; - } - } - - if (alreadyEnlisted > 0) { - result->set("state", "warning"); - result->set("msg", std::to_string(alreadyEnlisted) + " already enlisted"); - return result; - } - } - - - - result->set("state", "success"); - return result; - } - - } - catch (Poco::Exception& ex) { - printf("[JsonTransaction::handle] try to use params as jsonObject: %s\n", ex.displayText().data()); - result->set("state", "error"); - result->set("msg", "json exception"); - result->set("details", ex.displayText()); - return result; - } - } - else if (params.isVector()) { - const Poco::URI::QueryParameters queryParams = params.extract(); - auto transactionIT = queryParams.begin(); - for (auto it = queryParams.begin(); it != queryParams.end(); it++) { - if (it->first == "session_id") { - session_id = stoi(it->second); - //break; - } - else if (it->first == "transaction_base64") { - transactionIT = it; - } - } - if (session_id) { - auto sm = SessionManager::getInstance(); - auto session = sm->getSession(session_id); - if (!session) { - result->set("state", "error"); - result->set("msg", "session not found"); - return result; - } - if (!session->startProcessingTransaction(transactionIT->second)) { - auto lastError = session->getLastError(); - if (lastError) delete lastError; - result->set("state", "error"); - result->set("msg", "already enlisted"); - return result; - } - result->set("state", "success"); - return result; - } - else { - result->set("state", "error"); - result->set("msg", "session id not set"); - return result; - } - } - else if (params.isStruct()) { - result->set("state", "error"); - result->set("msg", "struct not implemented yet"); - } - else if (params.isArray()) { - result->set("state", "error"); - result->set("msg", "array not implemented yet"); - } - else if (params.isList()) { - result->set("state", "error"); - result->set("msg", "list not implemented yet"); - } - else if (params.isString()) { - result->set("state", "error"); - result->set("msg", "string not implemented yet"); - } - else if (params.isDeque()) { - result->set("state", "error"); - result->set("msg", "deque not implemented yet"); - } - else { - - result->set("state", "error"); - result->set("msg", "format not implemented"); - result->set("details", std::string(params.type().name())); - } - - return result; -} - +#include "JsonTransaction.h" +#include "Poco/URI.h" +#include "Poco/Dynamic/Struct.h" + +#include "../SingletonManager/SessionManager.h" +#include "../ServerConfig.h" + +Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params) +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + int session_id = 0; + + // if is json object + if (params.type() == typeid(Poco::JSON::Object::Ptr)) { + Poco::JSON::Object::Ptr paramJsonObject = params.extract(); + + try { + /// Throws a RangeException if the value does not fit + /// into the result variable. + /// Throws a NotImplementedException if conversion is + /// not available for the given type. + /// Throws InvalidAccessException if Var is empty. + paramJsonObject->get("session_id").convert(session_id); + auto sm = SessionManager::getInstance(); + if (session_id != 0) { + auto session = sm->getSession(session_id); + if (!session) { + result->set("state", "error"); + result->set("msg", "session not found"); + return result; + } + + int balance = 0; + + if (!paramJsonObject->isNull("balance")) { + paramJsonObject->get("balance").convert(balance); + if (balance) { + auto u = session->getUser(); + if (u) { + u->setBalance(balance); + } + auto nu = session->getNewUser(); + if (!nu.isNull()) { + nu->setBalance(balance); + } + } + } + + std::string transactionBase64String; + Poco::Dynamic::Var transaction_base64 = paramJsonObject->get("transaction_base64"); + int alreadyEnlisted = 0; + bool auto_sign = false; + auto auto_sign_json = paramJsonObject->get("auto_sign"); + if (!auto_sign_json.isEmpty()) { + auto_sign_json.convert(auto_sign); + } + + if (transaction_base64.isString()) { + paramJsonObject->get("transaction_base64").convert(transactionBase64String); + + if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) { + if (auto_sign) { + auto errorJson = session->getErrorsArray(); + result->set("state", "error"); + result->set("msg", "error processing transaction"); + result->set("details", errorJson); + return result; + } + auto lastError = session->getLastError(); + if (lastError) delete lastError; + result->set("state", "error"); + result->set("msg", "already enlisted"); + return result; + } + + } else { + Poco::DynamicStruct ds = *paramJsonObject; + int alreadyEnlisted = 0; + + for (int i = 0; i < ds["transaction_base64"].size(); i++) { + ds["transaction_base64"][i].convert(transactionBase64String); + if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) { + auto lastError = session->getLastError(); + if (lastError) delete lastError; + alreadyEnlisted++; + } + } + + if (alreadyEnlisted > 0) { + result->set("state", "warning"); + result->set("msg", std::to_string(alreadyEnlisted) + " already enlisted"); + return result; + } + } + + + + result->set("state", "success"); + return result; + } + + } + catch (Poco::Exception& ex) { + printf("[JsonTransaction::handle] try to use params as jsonObject: %s\n", ex.displayText().data()); + result->set("state", "error"); + result->set("msg", "json exception"); + result->set("details", ex.displayText()); + return result; + } + } + else if (params.isVector()) { + const Poco::URI::QueryParameters queryParams = params.extract(); + auto transactionIT = queryParams.begin(); + for (auto it = queryParams.begin(); it != queryParams.end(); it++) { + if (it->first == "session_id") { + session_id = stoi(it->second); + //break; + } + else if (it->first == "transaction_base64") { + transactionIT = it; + } + } + if (session_id) { + auto sm = SessionManager::getInstance(); + auto session = sm->getSession(session_id); + if (!session) { + result->set("state", "error"); + result->set("msg", "session not found"); + return result; + } + if (!session->startProcessingTransaction(transactionIT->second)) { + auto lastError = session->getLastError(); + if (lastError) delete lastError; + result->set("state", "error"); + result->set("msg", "already enlisted"); + return result; + } + result->set("state", "success"); + return result; + } + else { + result->set("state", "error"); + result->set("msg", "session id not set"); + return result; + } + } + else if (params.isStruct()) { + result->set("state", "error"); + result->set("msg", "struct not implemented yet"); + } + else if (params.isArray()) { + result->set("state", "error"); + result->set("msg", "array not implemented yet"); + } + else if (params.isList()) { + result->set("state", "error"); + result->set("msg", "list not implemented yet"); + } + else if (params.isString()) { + result->set("state", "error"); + result->set("msg", "string not implemented yet"); + } + else if (params.isDeque()) { + result->set("state", "error"); + result->set("meg", "deque not implemented yet"); + } + else { + + result->set("state", "error"); + result->set("msg", "format not implemented"); + result->set("details", std::string(params.type().name())); + } + + return result; +} diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index e5e4916ad..caa3f851a 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -21,6 +21,7 @@ namespace controller { : mPassword(nullptr), mGradidoKeyPair(nullptr), mCanDecryptPrivateKey(false), mGradidoCurrentBalance(0) { mDBModel = dbModel; + } User::~User() @@ -39,9 +40,9 @@ namespace controller { return Poco::AutoPtr(user); } - Poco::AutoPtr User::create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) + Poco::AutoPtr User::create(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) { - auto db = new model::table::User(email, first_name, last_name, passwordHashed, languageKey); + auto db = new model::table::User(email, first_name, last_name, group_id, passwordHashed, languageKey); auto user = new User(db); return Poco::AutoPtr(user); } @@ -327,6 +328,41 @@ namespace controller { return -1; } + /* + USER_EMPTY, + USER_LOADED_FROM_DB, + USER_PASSWORD_INCORRECT, + USER_PASSWORD_ENCRYPTION_IN_PROCESS, + USER_EMAIL_NOT_ACTIVATED, + USER_NO_KEYS, + USER_NO_PRIVATE_KEY, + USER_NO_GROUP, + USER_KEYS_DONT_MATCH, + USER_COMPLETE, + USER_DISABLED + */ + UserState User::getUserState() + { + std::unique_lock _lock(mSharedMutex); + auto model = getModel(); + if (!model->getID() && model->getEmail() == "") { + return USER_EMPTY; + } + if (!model->hasPrivateKeyEncrypted() && !model->hasPublicKey()) { + return USER_NO_KEYS; + } + if (!model->hasPrivateKeyEncrypted()) { + return USER_NO_PRIVATE_KEY; + } + if (!model->getGroupId()) { + return USER_NO_GROUP; + } + if (!model->isEmailChecked()) { + return USER_EMAIL_NOT_ACTIVATED; + } + return USER_COMPLETE; + } + int User::checkIfVerificationEmailsShouldBeResend(const Poco::Util::Timer& timer) { diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index f627fffc3..cd213c175 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -9,6 +9,21 @@ #include "TableControllerBase.h" +enum UserState +{ + USER_EMPTY, + USER_LOADED_FROM_DB, + USER_PASSWORD_INCORRECT, + USER_PASSWORD_ENCRYPTION_IN_PROCESS, + USER_EMAIL_NOT_ACTIVATED, + USER_NO_KEYS, + USER_NO_PRIVATE_KEY, + USER_NO_GROUP, + USER_KEYS_DONT_MATCH, + USER_COMPLETE, + USER_DISABLED +}; + namespace controller { @@ -26,7 +41,7 @@ namespace controller { ~User(); static Poco::AutoPtr create(); - static Poco::AutoPtr create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); + static Poco::AutoPtr create(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); static std::vector search(const std::string& searchString); @@ -95,6 +110,9 @@ namespace controller { //! \return -1 = stored pubkey and private key didn't match int setNewPassword(const std::string& password); + //! \brief calculate user state + UserState getUserState(); + //! \brief return AuthenticatedEncryption Auto Pointer inline const Poco::AutoPtr getPassword() { std::shared_lock _lock(mSharedMutex); diff --git a/src/cpp/controller/UserBackup.cpp b/src/cpp/controller/UserBackup.cpp index 9a152592f..88bc3f682 100644 --- a/src/cpp/controller/UserBackup.cpp +++ b/src/cpp/controller/UserBackup.cpp @@ -48,17 +48,12 @@ namespace controller { } - Poco::SharedPtr UserBackup::getKeyPair() + Poco::SharedPtr UserBackup::getKeyPair() { if (!mKeyPair.isNull()) { return mKeyPair; } - mKeyPair = new KeyPair; - auto model = getModel(); - auto passphrase = model->getPassphrase(); - - mKeyPair->generateFromPassphrase(passphrase); - return mKeyPair; + mKeyPair = createGradidoKeyPair(); } KeyPairEd25519* UserBackup::createGradidoKeyPair() @@ -77,17 +72,17 @@ namespace controller { return ""; } auto passphrase = getModel()->getPassphrase(); - Mnemonic* wordSource = nullptr; - if (KeyPair::validatePassphrase(passphrase, &wordSource)) { - for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { - Mnemonic* m = &ServerConfig::g_Mnemonic_WordLists[i]; - if (m == wordSource) { - if (type == i) { - return passphrase; - } - else { - return KeyPair::passphraseTransform(passphrase, m, &ServerConfig::g_Mnemonic_WordLists[type]); - } + auto wordSource = Passphrase::detectMnemonic(passphrase); + for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { + Mnemonic* m = &ServerConfig::g_Mnemonic_WordLists[i]; + if (m == wordSource) { + if (type == i) { + return passphrase; + } + else { + //return KeyPair::passphraseTransform(passphrase, m, &ServerConfig::g_Mnemonic_WordLists[type]); + auto passphrase_obj = Passphrase::create(passphrase, wordSource); + return passphrase_obj->transform(&ServerConfig::g_Mnemonic_WordLists[type])->getString(); } } } diff --git a/src/cpp/controller/UserBackup.h b/src/cpp/controller/UserBackup.h index a21d1c3ab..f1ab2f95a 100644 --- a/src/cpp/controller/UserBackup.h +++ b/src/cpp/controller/UserBackup.h @@ -2,7 +2,6 @@ #define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE #include "../model/table/UserBackup.h" -#include "../Crypto/KeyPair.h" #include "../Crypto/KeyPairEd25519.h" #include "Poco/SharedPtr.h" @@ -26,7 +25,7 @@ namespace controller { //! depracted //! \return create keyPair from passphrase if not exist, else return existing pointer - Poco::SharedPtr getKeyPair(); + Poco::SharedPtr getKeyPair(); //! \return newly created key pair from passphrase or nullptr if not possible, caller becomes owner of pointer KeyPairEd25519* createGradidoKeyPair(); @@ -38,7 +37,7 @@ namespace controller { protected: UserBackup(model::table::UserBackup* dbModel); - Poco::SharedPtr mKeyPair; + Poco::SharedPtr mKeyPair; }; } diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 783fdc2e8..217414aec 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -188,7 +188,7 @@ Poco::AutoPtr Session::getEmailVerificationCo return ret; } -bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email) +bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email, int group_id) { Profiler usedTime; @@ -218,7 +218,7 @@ bool Session::adminCreateUser(const std::string& first_name, const std::string& return false; } - auto newUser = controller::User::create(email, first_name, last_name); + auto newUser = controller::User::create(email, first_name, last_name, group_id); updateTimeout(); @@ -363,7 +363,8 @@ bool Session::createUser(const std::string& first_name, const std::string& last_ return true; } -bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password) + +bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password, int groupId) { std::unique_lock _lock(mSharedMutex); static const char* function_name = "Session::createUserDirect"; @@ -395,7 +396,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string& } // user - mNewUser = controller::User::create(email, first_name, last_name); + mNewUser = controller::User::create(email, first_name, last_name, groupId); auto user_model = mNewUser->getModel(); user_model->insertIntoDB(true); auto user_id = user_model->getID(); @@ -620,7 +621,7 @@ int Session::sendResetPasswordEmail(Poco::AutoPtr user, bool p return 0; } -int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource) +int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, const Mnemonic* wordSource) { KeyPair keys; static const char* functionName = "Session::comparePassphraseWithSavedKeys"; @@ -629,7 +630,9 @@ int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, sendErrorsAsEmail(); return -2; } - if (!keys.generateFromPassphrase(inputPassphrase.data(), wordSource)) { + auto passphrase = Passphrase::create(inputPassphrase, wordSource); + // if (!keys.generateFromPassphrase(inputPassphrase.data(), wordSource)) { + if (passphrase.isNull() || !passphrase->checkIfValid()) { addError(new ParamError(functionName, "invalid passphrase", inputPassphrase)); if (!mNewUser.isNull() && mNewUser->getModel()) { addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); @@ -651,9 +654,15 @@ int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, return -1; } } - if (0 == memcmp(userModel->getPublicKey(), keys.getPublicKey(), crypto_sign_PUBLICKEYBYTES)) { - mPassphrase = inputPassphrase; - return 1; + auto keys = KeyPairEd25519::create(passphrase); + if (keys) { + auto cmp_result = memcmp(userModel->getPublicKey(), keys->getPublicKey(), crypto_sign_PUBLICKEYBYTES); + delete keys; + keys = nullptr; + if (0 == cmp_result) { + mPassphrase = inputPassphrase; + return 1; + } } addError(new Error(gettext("Passphrase"), gettext("Das ist nicht die richtige Passphrase.")), false); return 0; @@ -675,11 +684,6 @@ bool Session::startProcessingTransaction(const std::string& proto_message_base64 return false; } } - if (mSessionUser.isNull() || !mSessionUser->getEmail()) { - addError(new Error(funcName, "user is zero")); - unlock(); - return false; - } Poco::AutoPtr processorTask( new ProcessingTransaction( @@ -789,15 +793,7 @@ size_t Session::getProcessingTransactionCount() return count; } -bool Session::isPwdValid(const std::string& pwd) -{ - if (mSessionUser) { - return mSessionUser->validatePwd(pwd, this); - } - return false; -} - -UserStates Session::loadUser(const std::string& email, const std::string& password) +UserState Session::loadUser(const std::string& email, const std::string& password) { static const char* functionName = "Session::loadUser"; auto observer = SingletonTaskObserver::getInstance(); @@ -808,14 +804,9 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo } //Profiler usedTime; //printf("before lock\n"); - lock(functionName); - //printf("locked \n"); - if (!mSessionUser.isNull() && mSessionUser->getEmail() != email) { - mSessionUser.assign(nullptr); - mNewUser.assign(nullptr); - //printf("user nullptr assigned\n"); - } - //printf("after checking if session user is null\n"); + //lock(functionName); + Poco::ScopedLock _lock(mWorkMutex); + //if (!mSessionUser) { if (mNewUser.isNull()) { //printf("new user is null\n"); @@ -831,50 +822,55 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo } //printf("before get model\n"); auto user_model = mNewUser->getModel(); - if (user_model && user_model->isDisabled()) { + if (user_model && user_model->isDisabled()) { return USER_DISABLED; } - //printf("before if login\n"); - if (!mSessionUser.isNull() && mSessionUser->getUserState() >= USER_LOADED_FROM_DB) { - //printf("before login\n"); - int loginResult = 0; + + if (mNewUser->getUserState() >= USER_LOADED_FROM_DB) { + + int loginResult = mNewUser->login(password); int exitCount = 0; - do { - loginResult = mNewUser->login(password); - Poco::Thread::sleep(100); - exitCount++; - } while (-3 == loginResult && exitCount < 15); - if (exitCount > 1) { - addError(new ParamError(functionName, "login succeed, retrys: ", exitCount)); - addError(new ParamError(functionName, "email: ", email)); - sendErrorsAsEmail(); - } - - if (exitCount >= 15) + if (loginResult == -3) { - auto running_password_creations = observer->getTasksCount(TASK_OBSERVER_PASSWORD_CREATION); + do + { + Poco::Thread::sleep(100); + loginResult = mNewUser->login(password); + exitCount++; + } while (-3 == loginResult && exitCount < 15); + if (exitCount > 1) + { + addError(new ParamError(functionName, "login succeed, retrys: ", exitCount)); + addError(new ParamError(functionName, "email: ", email)); + sendErrorsAsEmail(); + } - addError(new ParamError(functionName, "login failed after 15 retrys and 100 ms sleep between, currently running passwort creation tasks: ", running_password_creations)); - addError(new ParamError(functionName, "email: ", email)); - sendErrorsAsEmail(); - return USER_PASSWORD_ENCRYPTION_IN_PROCESS; + if (exitCount >= 15) + { + auto running_password_creations = observer->getTasksCount(TASK_OBSERVER_PASSWORD_CREATION); + + addError(new ParamError(functionName, "login failed after 15 retrys and 100 ms sleep between, currently running passwort creation tasks: ", running_password_creations)); + addError(new ParamError(functionName, "email: ", email)); + sendErrorsAsEmail(); + return USER_PASSWORD_ENCRYPTION_IN_PROCESS; + } } - //printf("new user login with result: %d\n", loginResult); - - if (-1 == loginResult) { + if (-1 == loginResult) + { addError(new Error(functionName, "error in user data set, saved pubkey didn't match extracted pubkey from private key")); addError(new ParamError(functionName, "user email", mNewUser->getModel()->getEmail())); sendErrorsAsEmail(); //unlock(); //return USER_KEYS_DONT_MATCH; } - if (0 == loginResult) { - unlock(); + if (0 == loginResult) + { return USER_PASSWORD_INCORRECT; } // error decrypting private key - if (-2 == loginResult) { + if (-2 == loginResult) + { // check if we have access to the passphrase, if so we can reencrypt the private key printf("try reencrypting key\n"); auto user_model = mNewUser->getModel(); @@ -899,45 +895,29 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo } } } - // can be removed if session user isn't used any more - // don't calculate password two times anymore - mSessionUser->login(mNewUser); - //printf("after old user login\n"); - /*if (mNewUser->getModel()->getPasswordHashed() && !mSessionUser->validatePwd(password, this)) { - unlock(); - return USER_PASSWORD_INCORRECT; - }*/ + } else { - //printf("before sleep\n"); - User::fakeCreateCryptoKey(); + Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime); } - /*if (!mSessionUser->validatePwd(password, this)) { - addError(new Error("Login", "E-Mail oder Passwort nicht korrekt, bitte versuche es erneut!")); - unlock(); - return false; - } - if (!mSessionUser->isEmailChecked()) { - addError(new Error("Account", "E-Mail Adresse wurde noch nicht bestätigt, hast du schon eine E-Mail erhalten?")); - unlock(); - return false; - }*/ - //printf("before detect session state\n"); detectSessionState(); - unlock(); - //printf("before return user state\n"); - return mSessionUser->getUserState(); + if (0 == mNewUser->getModel()->getGroupId()) { + return USER_NO_GROUP; + } + + return mNewUser->getUserState(); } bool Session::deleteUser() { lock("Session::deleteUser"); bool bResult = false; - if(mSessionUser) { + if(!mNewUser.isNull()) { JsonRequest phpServerRequest(ServerConfig::g_php_serverHost, 443); Poco::Net::NameValueCollection payload; - payload.add("user", std::string(mSessionUser->getPublicKeyHex())); + auto user_model = mNewUser->getModel(); + payload.add("user", user_model->getPublicKeyHex()); //auto ret = phpServerRequest.request("userDelete", payload); JsonRequestReturn ret = JSON_REQUEST_RETURN_OK; if (ret == JSON_REQUEST_RETURN_ERROR) { @@ -946,7 +926,7 @@ bool Session::deleteUser() sendErrorsAsEmail(); } else if (ret == JSON_REQUEST_RETURN_OK) { - bResult = mSessionUser->deleteFromDB(); + bResult = user_model->deleteFromDB(); } else { addError(new Error(gettext("Benutzer"), gettext("Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."))); @@ -999,14 +979,15 @@ SESSION_STATE_COUNT */ void Session::detectSessionState() { - if (mSessionUser.isNull() || !mSessionUser->hasCryptoKey()) { + + if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getPassword().isNull()) { return; } - UserStates userState = mSessionUser->getUserState(); + UserState userState = mNewUser->getUserState(); int checkEmail = -1, resetPasswd = -1; try { - auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mSessionUser->getDBId()); + auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mNewUser->getModel()->getID()); for (int i = 0; i < emailVerificationCodeObjects.size(); i++) { auto type = emailVerificationCodeObjects[i]->getModel()->getType(); @@ -1044,7 +1025,7 @@ void Session::detectSessionState() if (USER_NO_KEYS == userState) { - auto user_id = mSessionUser->getDBId(); + auto user_id = mNewUser->getModel()->getID(); auto userBackups = controller::UserBackup::load(user_id); // check passphrase, only possible while passphrase isn't crypted in db @@ -1052,15 +1033,20 @@ void Session::detectSessionState() // always trigger SESSION_STATE_PASSPHRASE_WRITTEN, else lost of data possible bool cryptedPassphrase = userBackups.size() > 0; for (auto it = userBackups.begin(); it != userBackups.end(); it++) { - KeyPair keys; auto passphrase = (*it)->getModel()->getPassphrase(); Mnemonic* wordSource = nullptr; - if (User::validatePassphrase(passphrase, &wordSource)) { - if (keys.generateFromPassphrase((*it)->getModel()->getPassphrase().data(), wordSource)) { - if (sodium_memcmp(mSessionUser->getPublicKey(), keys.getPublicKey(), ed25519_pubkey_SIZE) == 0) { - correctPassphraseFound = true; - break; - } + auto passphrase_obj = Passphrase::create(passphrase, wordSource); + if (!passphrase_obj.isNull() && passphrase_obj->checkIfValid()) { + auto key_pair = KeyPairEd25519::create(passphrase_obj); + if (key_pair && key_pair->isTheSame(mNewUser->getModel()->getPublicKey())) { + correctPassphraseFound = true; + //break; + } + if (key_pair) { + delete key_pair; + } + if (correctPassphraseFound) { + break; } } else { @@ -1143,8 +1129,7 @@ bool Session::loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode) addError(new Error(gettext("E-Mail Verification"), gettext("Fehler beim laden des Benutzers."))); return false; } - mSessionUser = new User(mNewUser); - mSessionUser->setLanguage(getLanguage()); + // TODO: Maybe update language key by user, is session has another, or update only with options-menu auto verificationType = mEmailVerificationCodeObject->getModel()->getType(); if (verificationType == model::table::EMAIL_OPT_IN_RESET_PASSWORD) { @@ -1222,21 +1207,7 @@ bool Session::useOrGeneratePassphrase(const std::string& passphase) } } */ -bool Session::generatePassphrase() -{ - if (mNewUser.isNull()) return false; - - auto lang = getLanguage(); - if (lang == LANG_EN) { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); - } - else { - mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - } - //mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]); - updateState(SESSION_STATE_PASSPHRASE_GENERATED); - return true; -} + bool Session::generateKeys(bool savePrivkey, bool savePassphrase) { diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index b8f2cc949..ca6365dff 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -11,7 +11,6 @@ #define DR_LUA_WEB_MODULE_SESSION_SESSION_H #include "../lib/NotificationList.h" -#include "User.h" #include "../controller/User.h" #include "../lib/MultithreadContainer.h" @@ -73,29 +72,20 @@ public: inline Poco::AutoPtr getNewUser() { return mNewUser; } // ---------------- User functions ---------------------------- - // TODO: register state: written into db, mails sended, update state only if new state is higher as old state - // create User send e-mail activation link - bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); //! \brief new register function, without showing user pubkeys, using controller/user - bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password, int groupId); // adminRegister without passwort - bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); + bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email, int group_id); // TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing - UserStates loadUser(const std::string& email, const std::string& password); + UserState loadUser(const std::string& email, const std::string& password); bool ifUserExist(const std::string& email); - - inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } - bool deleteUser(); - Poco::AutoPtr getUser() { - return mSessionUser; - } // ------------------------- Email Verification Code functions ------------------------------- @@ -117,7 +107,7 @@ public: //! \return 1 = same //! \return -1 = error //! \return -2 = critical error - int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource); + int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, const Mnemonic* wordSource); Poco::Net::HTTPCookie getLoginCookie(); @@ -132,14 +122,13 @@ public: inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; } inline const std::string& getOldPassphrase() { return mPassphrase; } - bool generatePassphrase(); + bool generateKeys(bool savePrivkey, bool savePassphrase); inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; } inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; } inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; } - bool isPwdValid(const std::string& pwd); void reset(); void updateState(SessionStates newState); @@ -204,7 +193,6 @@ protected: private: int mHandleId; - Poco::AutoPtr mSessionUser; Poco::AutoPtr mNewUser; std::string mPassphrase; Poco::AutoPtr mNewPassphrase; @@ -225,44 +213,6 @@ private: }; -class WriteEmailVerification : public UniLib::controller::CPUTask -{ -public: - WriteEmailVerification(Poco::AutoPtr user, Poco::AutoPtr emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) - : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - virtual const char* getResourceType() const { return "WriteEmailVerification"; }; - virtual int run(); - -private: - Poco::AutoPtr mUser; - Poco::AutoPtr mEmailVerificationCode; - -}; - -class WritePassphraseIntoDB : public UniLib::controller::CPUTask -{ -public: - WritePassphraseIntoDB(int userId, const std::string& passphrase) - : mUserId(userId), mPassphrase(passphrase) { -#ifdef _UNI_LIB_DEBUG - setName(std::to_string(userId).data()); -#endif - } - - - virtual int run(); - virtual const char* getResourceType() const { return "WritePassphraseIntoDB"; }; - -protected: - int mUserId; - std::string mPassphrase; -}; - class SessionStateUpdateCommand : public UniLib::controller::Command { public: diff --git a/src/cpp/model/TransactionCreation.cpp b/src/cpp/model/TransactionCreation.cpp index 65b1bf837..bf2825a74 100644 --- a/src/cpp/model/TransactionCreation.cpp +++ b/src/cpp/model/TransactionCreation.cpp @@ -4,17 +4,14 @@ //TransactionCreation::TransactionCreation(const std::string& memo, const model::messages::gradido::TransactionCreation& protoCreation) TransactionCreation::TransactionCreation(const std::string& memo, const proto::gradido::GradidoCreation& protoCreation) - : TransactionBase(memo), mProtoCreation(protoCreation), mReceiverUser(nullptr) + : TransactionBase(memo), mProtoCreation(protoCreation) { memset(mReceiverPublicHex, 0, 65); } TransactionCreation::~TransactionCreation() { - if (mReceiverUser) { - delete mReceiverUser; - mReceiverUser = nullptr; - } + } int TransactionCreation::prepare() @@ -40,15 +37,17 @@ int TransactionCreation::prepare() addError(new Error(functionName, "receiver public invalid (size not 32)")); return -2; } - mReceiverUser = new User((const unsigned char*)receiverPublic.data()); - getErrors(mReceiverUser); + mReceiverUser = controller::User::create(); + //mReceiverUser = new User((const unsigned char*)receiverPublic.data()); + mReceiverUser->load((const unsigned char*)receiverPublic.data()); + getErrors(mReceiverUser->getModel()); if (mReceiverUser->getUserState() == USER_EMPTY) { sodium_bin2hex(mReceiverPublicHex, 65, (const unsigned char*)receiverPublic.data(), receiverPublic.size()); delete mReceiverUser; mReceiverUser = nullptr; } else { - memcpy(mReceiverPublicHex, mReceiverUser->getPublicKeyHex().data(), 64); + memcpy(mReceiverPublicHex, mReceiverUser->getModel()->getPublicKeyHex().data(), 64); // uncomment because not correctly working /*if (!mReceiverUser->validateIdentHash(mProtoCreation.ident_hash())) { addError(new Error(functionName, "ident hash isn't the same")); diff --git a/src/cpp/model/TransactionCreation.h b/src/cpp/model/TransactionCreation.h index ff1fd62a8..fe695b89b 100644 --- a/src/cpp/model/TransactionCreation.h +++ b/src/cpp/model/TransactionCreation.h @@ -13,7 +13,7 @@ #include "TransactionBase.h" #include "../proto/gradido/GradidoCreation.pb.h" -#include "User.h" +#include "../controller/User.h" class TransactionCreation : public TransactionBase { @@ -23,7 +23,7 @@ public: int prepare(); - inline User* getUser() { return mReceiverUser; } + inline Poco::AutoPtr getUser() { return mReceiverUser; } inline google::protobuf::int64 getAmount() { return mProtoCreation.receiver().amount(); } inline char* getPublicHex() { return mReceiverPublicHex; } @@ -33,7 +33,7 @@ public: protected: const proto::gradido::GradidoCreation& mProtoCreation; char mReceiverPublicHex[65]; - User* mReceiverUser; + Poco::AutoPtr mReceiverUser; }; #endif //GRADIDO_LOGIN_SERVER_MODEL_TRANSACTION_CREATION_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp deleted file mode 100644 index a57324cf8..000000000 --- a/src/cpp/model/User.cpp +++ /dev/null @@ -1,1323 +0,0 @@ -#include "User.h" -#include "Session.h" -#include -#include "ed25519/ed25519.h" -#include "Poco/Util/Application.h" -#include "Poco/RegularExpression.h" -#include "../ServerConfig.h" - -#include "../SingletonManager/ConnectionManager.h" -#include "../SingletonManager/ErrorManager.h" -#include "../SingletonManager/SessionManager.h" -#include "../SingletonManager/LanguageManager.h" -#include "../SingletonManager/SingletonTaskObserver.h" - -#include "../controller/UserBackup.h" - - -#include "Poco/Data/Binding.h" - -using namespace Poco::Data::Keywords; - -//#define DEBUG_USER_DELETE_ENV - - -// ------------------------------------------------------------------------------------------------- - -UserCreateCryptoKey::UserCreateCryptoKey(Poco::AutoPtr user, Poco::AutoPtr newUser, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler) - : UniLib::controller::CPUTask(cpuScheduler), mUser(user), mNewUser(newUser), mPassword(password) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - -} - -int UserCreateCryptoKey::run() -{ - auto cryptoKey = mUser->createCryptoKey(mPassword); - mUser->setCryptoKey(cryptoKey); - - if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { - printf("[UserCreateCryptoKey] crypto_shorthash_BYTES != sizeof(mPasswordHashed)\n"); - throw Poco::Exception("crypto_shorthash_BYTES != sizeof(mPasswordHashed)"); - } - - auto pwdHashed = mUser->createPasswordHashed(cryptoKey); - mUser->setPwdHashed(pwdHashed); - mNewUser->getModel()->setPasswordHashed(pwdHashed); - - //printf("crypto key created\n"); - setTaskFinished(); - // must poke cpu scheduler manually because another task is waiting for this task, but in the other scheduler - ServerConfig::g_CPUScheduler->checkPendingTasks(); - return 0; -} - -// ------------------------------------------------------------------------------------------------------------- - -int UserGenerateKeys::run() -{ - - Mnemonic* wordList = nullptr; - if (!User::validatePassphrase(mPassphrase, &wordList)) { - mUser->addError(new Error(mUser->gettext("User generate Keys"), mUser->gettext("invalid passphrase, please notice the server admin coin@gradido.net"))); - return -2; - } - - // always return true, cannot fail (only if low on memory) - // !!! update: now can fail, if passphrase is invalid, for example if memory is corrupted - if (!mKeys.generateFromPassphrase(mPassphrase.data(), wordList)) { - mUser->addError(new Error(mUser->gettext("User generate Keys"), mUser->gettext("invalid passphrase2, please notice the server admin coin@gradido.net"))); - return -1; - } - - mUser->setPublicKeyHex(mKeys.getPubkeyHex()); - mUser->setPublicKey(mKeys.getPublicKey()); - - auto newUserModel = mNewUser->getModel(); - - newUserModel->setPublicKey(mKeys.getPublicKey()); - if (mUser->hasCryptoKey()) { - mUser->setPrivKey(mKeys.getPrivateKey()); - newUserModel->setPrivateKey(mUser->getPrivKey()); - } - - //printf("[UserGenerateKeys::run] controller::User: %d\n", (int)mNewUser.get()); - - return 0; -} - -// ----------------------------------------------------------------------------------------------------- - -int UserWriteIntoDB::run() -{ - auto cm = ConnectionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement insert = mUser->insertIntoDB(session); - try { - if (1 != insert.execute()) { - mUser->addError(new Error("User::insertIntoDB", "error by inserting data tuple to db")); - return -1; - } - } catch (Poco::Exception& ex) { - em->addError(new ParamError("[UserWriteIntoDB]", "error writing into db", ex.displayText().data())); - em->sendErrorsAsEmail(); - return -3; - } - if (!mUser->loadEntryDBId(session)) { - return -2; - } - return 0; -} - -// -------------------------------------------------------------------------------------------------------- - -UserWriteKeysIntoDB::UserWriteKeysIntoDB(std::vector parents, Poco::AutoPtr user, bool savePrivKey) - : UniLib::controller::CPUTask(parents.size()), mUser(user), mSavePrivKey(savePrivKey) -{ -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - if (parents.size() < 1 || strcmp(parents[0]->getResourceType(), "UserGenerateKeys") != 0) { - throw Poco::Exception("given TaskPtr isn't UserGenerateKeys"); - } - for (int i = 0; i < parents.size(); i++) { - setParentTaskPtrInArray(parents[i], i); - } - //setParentTaskPtrInArray(parents[0], 0); - -} - -int UserWriteKeysIntoDB::run() -{ - auto cm = ConnectionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - auto keyPairs = getParent(0).cast()->getKeyPairs(); - auto pubKey = keyPairs->getPublicKey(); - static const char* functionName = "UserWritePrivKeyIntoDB::run"; - - //printf("[UserWriteKeysIntoDB] after init\n"); - - Poco::Data::BLOB pubkey_blob(pubKey, crypto_sign_PUBLICKEYBYTES); - Poco::Data::Statement update(session); - Poco::Data::BLOB* pprivkey_blob = nullptr; - if (mSavePrivKey) { - //printf("[UserWriteKeysIntoDB] save privkey\n"); - // TODO: encrypt privkey - auto privKey = keyPairs->getPrivateKey(); - //printf("[UserWriteKeysIntoDB] privKey hex: %s\n", KeyPair::getHex(*privKey, privKey->size()).data()); - auto encryptedPrivKey = mUser->encrypt(privKey); - //pprivkey_blob = mUser->encrypt(privKey); - if (!encryptedPrivKey) { - em->addError(new Error(functionName, "no privkey found")); - em->sendErrorsAsEmail(); - return -1; - } - pprivkey_blob = new Poco::Data::BLOB(*encryptedPrivKey, encryptedPrivKey->size()); - //printf("[UserWriteKeysIntoDB] privkey encrypted\n"); - //Poco::Data::BLOB privkey_blob(*privKey, privKey->size()); - - update << "UPDATE users SET pubkey=?, privkey=? where id=?", - use(pubkey_blob), use(*pprivkey_blob), bind(mUser->getDBId()); - } - else { - update << "UPDATE users SET pubkey=? where id=?", - use(pubkey_blob), bind(mUser->getDBId()); - } - - try { - if (update.execute() != 1) { - em->addError(new ParamError(functionName, "error writing keys into db for user", std::to_string(mUser->getDBId()))); - em->sendErrorsAsEmail(); - if (pprivkey_blob) { - delete pprivkey_blob; - } - return -1; - } - } - catch (Poco::Exception& ex) { - em->addError(new ParamError(functionName, "mysql error updating", ex.displayText().data())); - em->sendErrorsAsEmail(); - if (pprivkey_blob) { - delete pprivkey_blob; - } - return -1; - } - - //printf("[UserWriteKeysIntoDB] after saving into db\n"); - if (pprivkey_blob) { - delete pprivkey_blob; - } - - return 0; -} - -// -------------------------------------------------------------------------------------------------------- - -UserWriteCryptoKeyHashIntoDB::UserWriteCryptoKeyHashIntoDB(Poco::AutoPtr user, int dependencieCount/* = 0*/) - : UniLib::controller::CPUTask(ServerConfig::g_CPUScheduler, dependencieCount), mUser(user) -{ -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif -} - -int UserWriteCryptoKeyHashIntoDB::run() -{ - mUser->updateIntoDB(USER_FIELDS_PASSWORD); - return 0; -} - -// ******************************************************************************* -// new user -User::User(const char* email, const char* first_name, const char* last_name) - : mState(USER_EMPTY), mDBId(0), mEmail(email), mFirstName(first_name), mLastName(last_name), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); -} -// load from db -User::User(const char* email) - : mState(USER_EMPTY), mDBId(0), mEmail(email), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - //crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); - //memset(mPasswordHashed, 0, crypto_shorthash_BYTES); - auto cm = ConnectionManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES); - - Poco::Nullable pubkey; - Poco::Nullable privkey; - - Poco::Data::Statement select(session); - int email_checked = 0; - std::string language_key; - select << "SELECT id, first_name, last_name, password, pubkey, privkey, email_checked, language from users where email = ?", - into(mDBId), into(mFirstName), into(mLastName), into(mPasswordHashed), into(pubkey), into(privkey), into(email_checked), into(language_key), - use(mEmail); - try { - auto result = select.execute(); - if (result == 1) { - mState = USER_LOADED_FROM_DB; - mLanguage = LanguageManager::languageFromString(language_key); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - if (email_checked == 0) { mState = USER_EMAIL_NOT_ACTIVATED;} - else if (pubkey.isNull()) { mState = USER_NO_KEYS;} - else if (privkey.isNull()) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE;} - - mEmailChecked = email_checked == 1; - - if (!pubkey.isNull()) { - auto pubkey_value = pubkey.value(); - if (pubkey_value.size() == crypto_sign_PUBLICKEYBYTES) { - memcpy(mPublicKey, pubkey_value.content().data(), crypto_sign_PUBLICKEYBYTES); - } - else { - addError(new Error("User", "pubkey from db has other size as expected")); - } - size_t hexSize = pubkey_value.size() * 2 + 1; - char* hexString = (char*)malloc(hexSize); - memset(hexString, 0, hexSize); - sodium_bin2hex(hexString, hexSize, pubkey_value.content().data(), pubkey_value.size()); - mPublicHex = hexString; - free(hexString); - } - if (!privkey.isNull()) { - auto privkey_value = privkey.value(); - auto privkey_size = privkey_value.size(); - //mPrivateKey = new ObfusArray(privkey_value.size(), privkey_value.content().data()); - mPrivateKey = MemoryManager::getInstance()->getFreeMemory(privkey_size); - memcpy(*mPrivateKey, privkey_value.content().data(), privkey_size); - } - - } - } catch(Poco::Exception& ex) { - addError(new ParamError("User::User", "mysql error", ex.displayText().data())); - } -} - -User::User(int user_id) - : mState(USER_EMPTY), mDBId(user_id), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - auto cm = ConnectionManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - memset(mPublicKey, 0, crypto_sign_PUBLICKEYBYTES); - - Poco::Nullable pubkey; - Poco::Nullable privkey; - - Poco::Data::Statement select(session); - int email_checked = 0; - std::string language_key; - select << "SELECT email, first_name, last_name, password, pubkey, privkey, email_checked, language from users where id = ?", - into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(pubkey), into(privkey), into(email_checked), into(language_key), - use(user_id); - try { - auto result = select.execute(); - if (result == 1) { - mState = USER_LOADED_FROM_DB; - mLanguage = LanguageManager::languageFromString(language_key); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - if (email_checked == 0) { mState = USER_EMAIL_NOT_ACTIVATED; } - else if (pubkey.isNull()) { mState = USER_NO_KEYS; } - else if (privkey.isNull()) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE; } - - mEmailChecked = email_checked == 1; - - if (!pubkey.isNull()) { - auto pubkey_value = pubkey.value(); - if (pubkey_value.size() == crypto_sign_PUBLICKEYBYTES) { - memcpy(mPublicKey, pubkey_value.content().data(), crypto_sign_PUBLICKEYBYTES); - } - else { - addError(new Error("User", "pubkey from db has other size as expected")); - } - size_t hexSize = pubkey_value.size() * 2 + 1; - char* hexString = (char*)malloc(hexSize); - memset(hexString, 0, hexSize); - sodium_bin2hex(hexString, hexSize, pubkey_value.content().data(), pubkey_value.size()); - mPublicHex = hexString; - free(hexString); - } - if (!privkey.isNull()) { - auto privkey_value = privkey.value(); - auto privkey_size = privkey_value.size(); - //mPrivateKey = new ObfusArray(privkey_value.size(), privkey_value.content().data()); - mPrivateKey = MemoryManager::getInstance()->getFreeMemory(privkey_size); - memcpy(*mPrivateKey, privkey_value.content().data(), privkey_size); - } - } - } - catch (Poco::Exception& ex) { - addError(new ParamError("User::User", "mysql error", ex.displayText().data())); - } -} - -User::User(const unsigned char* pubkey_array) - : mState(USER_EMPTY), mDBId(0), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - //crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); - //memset(mPasswordHashed, 0, crypto_shorthash_BYTES); - auto cm = ConnectionManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - memcpy(mPublicKey, pubkey_array, crypto_sign_PUBLICKEYBYTES); - - Poco::Data::BLOB pubkey(pubkey_array, 32); - Poco::Nullable privkey; - - Poco::Data::Statement select(session); - int email_checked = 0; - std::string language_key; - select << "SELECT id, email, first_name, last_name, password, privkey, email_checked, language from users where pubkey = ?", - into(mDBId), into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(privkey), into(email_checked), into(language_key), - use(pubkey); - try { - auto result = select.execute(); - if (result == 1) { - mState = USER_LOADED_FROM_DB; - mLanguage = LanguageManager::languageFromString(language_key); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - if (email_checked == 0) { mState = USER_EMAIL_NOT_ACTIVATED; } - else if (privkey.isNull()) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE; } - - mEmailChecked = email_checked == 1; - - size_t hexSize = pubkey.size() * 2 + 1; - char* hexString = (char*)malloc(hexSize); - memset(hexString, 0, hexSize); - sodium_bin2hex(hexString, hexSize, pubkey.content().data(), pubkey.size()); - mPublicHex = hexString; - free(hexString); - - if (!privkey.isNull()) { - auto privkey_value = privkey.value(); - auto privkey_size = privkey_value.size(); - //mPrivateKey = new ObfusArray(privkey_value.size(), privkey_value.content().data()); - mPrivateKey = MemoryManager::getInstance()->getFreeMemory(privkey_size); - memcpy(*mPrivateKey, privkey_value.content().data(), privkey_size); - } - - } - - } - catch (Poco::Exception& ex) { - addError(new ParamError("User::User", "mysql error", ex.displayText().data())); - } -} - -User::User(Poco::AutoPtr ctrl_user) - : mUserCtrl(ctrl_user), mState(USER_EMPTY), mDBId(0), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false), - mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1) -{ - assert(!ctrl_user.isNull()); - auto model = ctrl_user->getModel(); - assert(model); - - auto mm = MemoryManager::getInstance(); - mDBId = model->getID(); - mEmail = model->getEmail(); - mFirstName = model->getFirstName(); - mLastName = model->getLastName(); - mPasswordHashed = model->getPasswordHashed(); - auto pubkey = model->getPublicKey(); - if (pubkey) { - memcpy(mPublicKey, pubkey, crypto_sign_PUBLICKEYBYTES); - - size_t hexSize = crypto_sign_PUBLICKEYBYTES * 2 + 1; - auto hexStringTemp = mm->getFreeMemory(hexSize); - //char* hexString = (char*)malloc(hexSize); - memset(*hexStringTemp, 0, hexSize); - sodium_bin2hex((char*)(*hexStringTemp), hexSize, pubkey, crypto_sign_PUBLICKEYBYTES); - mPublicHex = std::string((char*)(*hexStringTemp)); - mm->releaseMemory(hexStringTemp); - } - if (model->hasPrivateKeyEncrypted()) { - auto privKeyVetor = model->getPrivateKeyEncrypted(); - mPrivateKey = mm->getFreeMemory(privKeyVetor.size()); - memcpy(*mPrivateKey, privKeyVetor.data(), privKeyVetor.size()); - } - mEmailChecked = model->isEmailChecked(); - mLanguage = LanguageManager::languageFromString(model->getLanguageKey()); - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage); - - /* - USER_EMPTY, - USER_LOADED_FROM_DB, - USER_PASSWORD_INCORRECT, - USER_PASSWORD_ENCRYPTION_IN_PROCESS, - USER_EMAIL_NOT_ACTIVATED, - USER_NO_KEYS, - USER_NO_PRIVATE_KEY, - USER_COMPLETE - */ - - if (mEmail != "") { - mState = USER_LOADED_FROM_DB; - - if (!mEmailChecked) { mState = USER_EMAIL_NOT_ACTIVATED; } - else if (!pubkey) { mState = USER_NO_KEYS; } - else if (!mPrivateKey) { mState = USER_NO_PRIVATE_KEY; } - else { mState = USER_COMPLETE; } - } -} - - -User::~User() -{ -#ifdef DEBUG_USER_DELETE_ENV - printf("[User::~User]\n"); -#endif - auto mm = MemoryManager::getInstance(); - if (mCryptoKey) { - //delete mCryptoKey; - mm->releaseMemory(mCryptoKey); - mCryptoKey = nullptr; - } - if (mPrivateKey) { - //delete mPrivateKey; - mm->releaseMemory(mPrivateKey); - mPrivateKey = nullptr; - } -} - -void User::setLanguage(Languages lang) -{ - lock("User::setLanguage"); - if (mLanguage != lang) { - mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(lang); - } - mLanguage = lang; - unlock(); -} - - -std::string User::generateNewPassphrase(Mnemonic* word_source) -{ - auto em = ErrorManager::getInstance(); - static const char* errorMessageForUser = "Ein Fehler, bitte wende dich an den Server-Admin (coin@gradido.net). | An error occured, please ask the server admin (coin@gradido.net)."; - unsigned int random_indices[PHRASE_WORD_COUNT]; - unsigned int str_sizes[PHRASE_WORD_COUNT]; - unsigned int phrase_buffer_size = 0; - bool errorReloadingMnemonicWordList = false; - int loopTrys = 0; - Poco::RegularExpression checkValidWord("^[a-zA-ZÄÖÜäöüß&;]*$"); - - // TODO: make sure words didn't double - for (int i = 0; i < PHRASE_WORD_COUNT; i++) { - random_indices[i] = randombytes_random() % 2048; - auto word = word_source->getWord(random_indices[i]); - if (loopTrys > 10 || errorReloadingMnemonicWordList) { - return errorMessageForUser; - } - if (!word) { - em->addError(new ParamError("User::generateNewPassphrase", "empty word get for index", random_indices[i])); - em->sendErrorsAsEmail(); - - random_indices[i] = randombytes_random() % 2048; - word = word_source->getWord(random_indices[i]); - if (!word) return errorMessageForUser; - - } - else { - if (!checkValidWord.match(word, 0, Poco::RegularExpression::RE_NOTEMPTY)) { - em->addError(new ParamError("User::generateNewPassphrase", "invalid word", word)); - em->addError(new Error("User::generateNewPassphrase", "try to reload mnemonic word list, but this error is maybe evidence for a serious memory problem!!!")); - if (!ServerConfig::loadMnemonicWordLists()) { - em->addError(new Error("User::generateNewPassphrase", "error reloading mnemonic word lists")); - errorReloadingMnemonicWordList = true; - } - else { - i = 0; - loopTrys++; - } - em->sendErrorsAsEmail(); - //return "Server Fehler, bitte frage den Admin coin@gradido.net | Server error, please ask the admin coin@gradido.net"; - } - } - str_sizes[i] = strlen(word); - phrase_buffer_size += str_sizes[i]; - } - phrase_buffer_size += PHRASE_WORD_COUNT + 1; - - std::string phrase_buffer(phrase_buffer_size, '\0'); - int phrase_buffer_cursor = 0; - - for (int i = 0; i < PHRASE_WORD_COUNT; i++) { - memcpy(&phrase_buffer[phrase_buffer_cursor], word_source->getWord(random_indices[i]), str_sizes[i]); - - phrase_buffer_cursor += str_sizes[i]; - phrase_buffer[phrase_buffer_cursor++] = ' '; - } - - - return phrase_buffer; -} - -bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/) -{ - return KeyPair::validatePassphrase(passphrase, wordSource); - -} - -bool User::isEmptyPassword() -{ - bool bRet = false; - lock("User::isEmptyPassword"); - //printf("[User::isEmptyPassword] pwd hashed: %d, running: %d, this: %d\n", -// mPasswordHashed, !mCreateCryptoKeyTask.isNull(), this); - bRet = mPasswordHashed == 0 && (mCreateCryptoKeyTask.isNull() || mCreateCryptoKeyTask->isTaskFinished()); - unlock(); - return bRet; -} - -UserStates User::getUserState() -{ - UserStates state; - lock("User::getUserState"); - state = mState; - unlock(); - return state; -} - -Poco::JSON::Object User::getJson() -{ - lock("User::getJson"); - Poco::JSON::Object userObj; - - userObj.set("first_name", mFirstName); - userObj.set("last_name", mLastName); - userObj.set("email", mEmail); - userObj.set("public_hex", mPublicHex); - userObj.set("state", userStateToString(mState)); - userObj.set("email_checked", mEmailChecked); - userObj.set("ident_hash", DRMakeStringHash(mEmail.data(), mEmail.size())); - unlock(); - return userObj; -} - -/* -// TODO: if a password and privkey already exist, load current private key and re encrypt with new crypto key -bool User::setNewPassword(const std::string& newPassword) -{ - //Profiler timeUsed; - if (newPassword == "") { - lock("User::setNewPassword"); - addError(new Error("Passwort", "Ist leer.")); - unlock(); - return false; - } - if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) { - lock("User::setNewPassword"); - addError(new Error("Passwort", "Wird bereits erstellt, bitte in ca. 1 minute neuladen.")); - unlock(); - return false; - } - duplicate(); - lock("User::setNewPassword"); - //printf("[User::setNewPassword] start create crypto key task with this: %d\n", this); - mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newPassword, ServerConfig::g_CPUScheduler); - mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask); - unlock(); - - duplicate(); - - UniLib::controller::TaskPtr savePassword(new UserWriteCryptoKeyHashIntoDB(this, 1)); - savePassword->setParentTaskPtrInArray(mCreateCryptoKeyTask, 0); - savePassword->scheduleTask(savePassword); - - - //printf("[User::setNewPassword] timeUsed: %s\n", timeUsed.string().data()); - return true; -} -*/ -bool User::updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser) -{ - static const char* functionName("User::updatePassword"); - if (newPassword == "") { - lock(functionName); - addError(new Error(gettext("Passwort"), gettext("Ist leer."))); - unlock(); - return false; - } - if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) { - lock(functionName); - addError(new Error(gettext("Passwort"), gettext("Wird bereits erstellt, bitte in ca. 1 minute neuladen."))); - unlock(); - return false; - } - //duplicate(); - //lock("User::setNewPassword"); - //printf("[User::setNewPassword] start create crypto key task with this: %d\n", this); - //mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newPassword, ServerConfig::g_CPUScheduler); - //mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask); - //unlock(); - - auto mm = MemoryManager::getInstance(); - - bool passwordHashedCalculated = false; - - // no previous password set - - //if (!mPasswordHashed) { - duplicate(); - lock(functionName); - //printf("[User::setNewPassword] start create crypto key task with this: %d\n", this); - mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newUser, newPassword, ServerConfig::g_CPUScheduler); - mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask); - unlock(); - //} - /*else { - // compare with previous password - auto cryptoKey = createCryptoKey(newPassword); - auto passwordHash = createPasswordHashed(cryptoKey); - lock(functionName); - if (mPasswordHashed == passwordHash) { - addError(new Error(gettext("Passwort"), gettext("Du hast dasselbe Passwort gewählt, bitte wähle ein anderes."))); - unlock(); - mm->releaseMemory(cryptoKey); - return false; - } - mPasswordHashed = passwordHash; - passwordHashedCalculated = true; - if (mCryptoKey) { - mm->releaseMemory(mCryptoKey); - } - mCryptoKey = cryptoKey; - unlock(); - }*/ - - duplicate(); - UniLib::controller::TaskPtr savePassword(nullptr); - UserWriteCryptoKeyHashIntoDB* writePWDHashedIntoDB = nullptr; - if (passwordHashedCalculated) { - savePassword = new UserWriteCryptoKeyHashIntoDB(this, 0); - } - else { - savePassword = new UserWriteCryptoKeyHashIntoDB(this, 1); - savePassword->setParentTaskPtrInArray(mCreateCryptoKeyTask, 0); - } - savePassword->scheduleTask(savePassword); - - if (passphrase != "") { - duplicate(); - UniLib::controller::TaskPtr genKeys(new UserGenerateKeys(this, newUser, passphrase)); - genKeys->scheduleTask(genKeys); - - - std::vector saveKeysParents; - saveKeysParents.reserve(2); // to prevent allocating more memory as ever needed - saveKeysParents.push_back(genKeys); - if (!passwordHashedCalculated) { - saveKeysParents.push_back(mCreateCryptoKeyTask); - } - duplicate(); - UniLib::controller::TaskPtr saveKeys(new UserWriteKeysIntoDB(saveKeysParents, this, true)); - saveKeys->scheduleTask(saveKeys); - } - - //printf("[User::setNewPassword] timeUsed: %s\n", timeUsed.string().data()); - return true; -} - -void User::setEmailChecked() -{ - lock("User::setEmailChecked"); - mEmailChecked = true; - if (mState <= USER_EMAIL_NOT_ACTIVATED) { - if (mPublicHex == "") { - mState = USER_NO_KEYS; - } - else if (!mPrivateKey) { - mState = USER_NO_PRIVATE_KEY; - } - else { - mState = USER_COMPLETE; - } - } - unlock(); -} - -bool User::validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint) -{ - auto mm = MemoryManager::getInstance(); - auto cmpCryptoKey = createCryptoKey(pwd); - if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { - throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); - } - if (nullptr == cmpCryptoKey) { - if (validationErrorsToPrint) { - validationErrorsToPrint->addError(new Error("User::validatePwd", "couldn't create crypto key")); - return false; - } - } - User::passwordHashed pwdHashed; - if (!ServerConfig::g_ServerCryptoKey) { - if (validationErrorsToPrint) { - validationErrorsToPrint->addError(new Error("User::validatePwd", "server crypto key not set")); - } - mm->releaseMemory(cmpCryptoKey); - return false; - } - crypto_shorthash((unsigned char*)&pwdHashed, *cmpCryptoKey, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey); - lock("User::validatePwd"); - if (pwdHashed == mPasswordHashed) { - if (!mCryptoKey) { - mCryptoKey = cmpCryptoKey; - } - else { - //delete cmpCryptoKey; - mm->releaseMemory(cmpCryptoKey); - } - unlock(); - return true; - } - //delete cmpCryptoKey; - mm->releaseMemory(cmpCryptoKey); - - unlock(); - return false; -} - -void User::login(Poco::AutoPtr newUser) -{ - assert(!newUser.isNull()); - assert(newUser->getModel()); - - lock("User::validatePwd"); - mPasswordHashed = newUser->getModel()->getPasswordHashed(); - auto mm = MemoryManager::getInstance(); - if (mCryptoKey) { - mm->releaseMemory(mCryptoKey); - mCryptoKey = nullptr; - } - auto keyPair = newUser->getGradidoKeyPair(); - if (keyPair) { - mCryptoKey = keyPair->getCryptedPrivKey(newUser->getPassword()); - } - unlock(); -} - -bool User::validateIdentHash(HASH hash) -{ - lock("User::validateIdentHash"); - HASH local_hash = DRMakeStringHash(mEmail.data(), mEmail.size()); - unlock(); - return local_hash == hash; -} - -bool User::deleteFromDB() -{ - auto cm = ConnectionManager::getInstance(); - auto em = ErrorManager::getInstance(); - auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - - Poco::Data::Statement deleteFromDB(session); - //DELETE FROM `table_name` [WHERE condition]; - - std::string tables[] = { "users", "email_opt_in", "user_backups" }; - - /*deleteFromDB - << "DELETE from users where id = ?;" - "DELETE from email_opt_in where user_id = ?;" - "DELETE from user_backups where user_id = ?", - use(mDBId), use(mDBId), use(mDBId); - */ - for (int i = 0; i < 3; i++) { - if (i > 0) { - deleteFromDB.reset(session); - deleteFromDB << "DELETE from " << tables[i] << " where user_id = ?", use(mDBId); - } - else { - deleteFromDB << "DELETE from " << tables[i] << " where id = ?", use(mDBId); - } - - try { - lock("User::deleteFromDB"); - auto result = deleteFromDB.execute(); - unlock(); - //printf("[User::deleteFromDB] %s deleted: %d\n", tables[i].data(), result); - } - catch (Poco::Exception& ex) { - unlock(); - em->addError(new ParamError("[User::deleteFromDB]", "error deleting user tables", ex.displayText().data())); - em->sendErrorsAsEmail(); - //return false; - } - } - - - return true; -} - -void User::duplicate() -{ - Poco::Mutex::ScopedLock _lock(mReferenceMutex); - //mReferenceMutex.lock(); - mReferenceCount++; -#ifdef DEBUG_USER_DELETE_ENV - printf("[User::duplicate] new value: %d\n", mReferenceCount); -#endif - //mReferenceMutex.unlock(); -} - -void User::release() -{ - - Poco::Mutex::ScopedLock _lock(mReferenceMutex); - //mReferenceMutex.lock(); - mReferenceCount--; -#ifdef DEBUG_USER_DELETE_ENV - printf("[User::release] new value: %d, this: %d\n", mReferenceCount, this); -#endif - if (0 == mReferenceCount) { - //mReferenceMutex.unlock(); - delete this; - return; - } - //mReferenceMutex.unlock(); - -} - -MemoryBin* User::createCryptoKey(const std::string& password) -{ - - //Profiler timeUsed; - auto mm = MemoryManager::getInstance(); - auto observer = SingletonTaskObserver::getInstance(); - static const char* funcName = "User::createCryptoKey"; - if (mEmail == "") { - lock(funcName); - addError(new Error(funcName, "email is empty")); - unlock(); - return nullptr; - } - - - - // TODO: put it in secure location, or use value from server config - static const unsigned char app_secret[] = { 0x21, 0xff, 0xbb, 0xc6, 0x16, 0xfe }; - - sha_context context_sha512; - //unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE); - if (SHA_512_SIZE < crypto_pwhash_SALTBYTES) { - lock(funcName); - addError(new Error(funcName, "sha512 is to small for libsodium pwhash saltbytes")); - unlock(); - return nullptr; - } - - observer->addTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION); - - unsigned char hash512_salt[SHA_512_SIZE]; // need at least crypto_pwhash_SALTBYTES 16U - sha512_init(&context_sha512); - sha512_update(&context_sha512, (const unsigned char*)mEmail.data(), mEmail.size()); - sha512_update(&context_sha512, app_secret, 6); - sha512_final(&context_sha512, hash512_salt); - - - //unsigned char* key = (unsigned char *)malloc(crypto_box_SEEDBYTES); // 32U - //ObfusArray* key = new ObfusArray(crypto_box_SEEDBYTES); - auto key = mm->getFreeMemory(crypto_box_SEEDBYTES); - //Bin32Bytes* key = mm->get32Bytes(); - if (crypto_pwhash(*key, key->size(), password.data(), password.size(), hash512_salt, 10U, 33554432, 2) != 0) { - lock(funcName); - addError(new ParamError(funcName, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno))); - unlock(); - observer->removeTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION); - //printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno)); - //printf("pwd: %s\n", pwd); - return nullptr; - } - observer->removeTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION); - -// lock(); -// auto cryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key); -// unlock(); -// free(key); - - // mCryptoKey - //printf("[User::createCryptoKey] time used: %s\n", timeUsed.string().data()); - return key; -} - -User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver/* = nullptr*/) -{ - if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { - throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); - } - User::passwordHashed pwdHashed = 0; - if (!ServerConfig::g_ServerCryptoKey) { - if (errorReceiver) { - errorReceiver->addError(new Error("User::validatePwd", "server crypto key not set")); - } - return pwdHashed; - } - crypto_shorthash((unsigned char*)&pwdHashed, *cryptoKey, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey); - - return pwdHashed; -} - -void User::fakeCreateCryptoKey() -{ - Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime); -} - -bool User::generateKeys(bool savePrivkey, const std::string& passphrase, Session* session) -{ - //Profiler timeUsed; - - duplicate(); - UniLib::controller::TaskPtr generateKeysTask(new UserGenerateKeys(this, session->getNewUser(), passphrase)); - //generateKeysTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_KEY_PAIR_GENERATED, session)); - //generateKeysTask->scheduleTask(generateKeysTask); - // run directly because we like to show pubkey on interface, shouldn't last to long - generateKeysTask->run(); - session->updateState(SESSION_STATE_KEY_PAIR_GENERATED); - - if (mDBId == 0) { - //printf("[User::generateKeys] dbid is zero, load from db\n"); - loadEntryDBId(ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); - if (mDBId == 0) { - auto em = ErrorManager::getInstance(); - em->addError(new ParamError("User::generateKeys", "user not found in db with email", mEmail.data())); - em->sendErrorsAsEmail(); - } - return false; - } - - duplicate(); - std::vector parentsForWriteKeys; - parentsForWriteKeys.reserve(2); - parentsForWriteKeys.push_back(generateKeysTask); - if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) { - parentsForWriteKeys.push_back(mCreateCryptoKeyTask); - } - - UniLib::controller::TaskPtr saveKeysTask(new UserWriteKeysIntoDB(parentsForWriteKeys, this, savePrivkey)); - saveKeysTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_KEY_PAIR_WRITTEN, session)); - saveKeysTask->scheduleTask(saveKeysTask); - - -// printf("[User::generateKeys] call two tasks, time used: %s\n", timeUsed.string().data()); - return true; - -} - -MemoryBin* User::encrypt(const MemoryBin* data) -{ - if (!hasCryptoKey()) { - addError(new Error("User::encrypt", "hasn't crypto key")); - return nullptr; - } - if (!data) { - addError(new Error("User::encrypt", "data is zero")); - return nullptr; - } - size_t message_len = data->size(); - size_t ciphertext_len = crypto_secretbox_MACBYTES + message_len; - - unsigned char nonce[crypto_secretbox_NONCEBYTES]; - // we use a hardcoded value for nonce - memset(nonce, 31, crypto_secretbox_NONCEBYTES); - - //unsigned char* ciphertext = (unsigned char*)malloc(ciphertext_len); - //ObfusArray* ciphertext = new ObfusArray(ciphertext_len); - auto mm = MemoryManager::getInstance(); - auto ciphertext = mm->getFreeMemory(ciphertext_len); - memset(*ciphertext, 0, ciphertext_len); - - if (0 != crypto_secretbox_easy(*ciphertext, *data, message_len, nonce, *mCryptoKey)) { - //printf("[%s] error encrypting message \n", __FUNCTION__); - addError(new Error("User::encrypt", "encrypting message failed")); - //free(ciphertext); - mm->releaseMemory(ciphertext); - - return nullptr; - } - - //printf("[User::encrypt] encrypted: %s, ciphertext len: %u\n", KeyPair::getHex(ciphertext, ciphertext_len).data(), ciphertext_len); - - //auto resultObfus = new ObfusArray(ciphertext_len, ciphertext); - //free(ciphertext); - - return ciphertext; -} - -MemoryBin* User::decrypt(const MemoryBin* encryptedData) -{ - if (!hasCryptoKey()) { - addError(new Error("User::decrypt", "hasn't crypto key")); - return nullptr; - } - //printf("[User::decrypt] decrypt: %s, ciphertext len: %u\n", KeyPair::getHex(*encryptedData, encryptedData->size()).data(), encryptedData->size()); - //ObfusArray* decrypetData = new ObfusArray(encryptedData->size() - crypto_secretbox_MACBYTES); - - size_t decryptSize = encryptedData->size() - crypto_secretbox_MACBYTES; - //unsigned char* decryptBuffer = (unsigned char*)malloc(decryptSize); - auto mm = MemoryManager::getInstance(); - //ObfusArray* decryptedData = new ObfusArray(decryptSize); - auto decryptedData = mm->getFreeMemory(decryptSize); - unsigned char nonce[crypto_secretbox_NONCEBYTES]; - // we use a hardcoded value for nonce - memset(nonce, 31, crypto_secretbox_NONCEBYTES); - - if (crypto_secretbox_open_easy(*decryptedData, *encryptedData, encryptedData->size(), nonce, *mCryptoKey)) { - mm->releaseMemory(decryptedData); - addError(new Error("User::decrypt", "error decrypting")); - return nullptr; - } - /*int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, - unsigned long long clen, const unsigned char *n, - const unsigned char *k);*/ - - return decryptedData; -} - -MemoryBin* User::sign(const unsigned char* message, size_t messageSize) -{ - - if (!message || !messageSize) return nullptr; - if (!hasCryptoKey()) { - addError(new Error("User::sign", "hasn't crypto key")); - return nullptr; - } - if (!mPrivateKey) { - addError(new Error("User::sign", "hasn't privkey")); - return nullptr; - } - - //binArrayObj = new BinaryArray(crypto_sign_BYTES); - auto mm = MemoryManager::getInstance(); - //auto signBinBuffer = (unsigned char*)malloc(crypto_sign_BYTES); - auto privKey = getPrivKey(); - - if (!privKey) { - //addError(new Error("User::sign", "decrypt privkey failed")); - - - auto userBackups = controller::UserBackup::load(mDBId); - - // get privkey, only possible while passphrase isn't crypted in db - bool correctPassphraseFound = false; - KeyPair keys; - for (auto it = userBackups.begin(); it != userBackups.end(); it++) { - - auto passphrase = (*it)->getModel()->getPassphrase(); - Mnemonic* wordSource = nullptr; - if (User::validatePassphrase(passphrase, &wordSource)) { - if (keys.generateFromPassphrase((*it)->getModel()->getPassphrase().data(), wordSource)) { - if(keys.isPubkeysTheSame(getPublicKey())) - { - correctPassphraseFound = true; - break; - } - } - } - } - if (correctPassphraseFound) { - - // save corrected key into db - auto encyrptedPrivKey = encrypt(keys.getPrivateKey()); - auto newUser = controller::User::create(); - if (1 == newUser->load(mDBId)) { - auto userModel = newUser->getModel(); - if (encyrptedPrivKey) { - userModel->setPrivateKey(encyrptedPrivKey); - userModel->updatePrivkey(); - // remove unencrypt error from priv key to prevent error 404 forwarding - delete getLastError(); - } - - mm->releaseMemory(encyrptedPrivKey); - - } - - // sign with received key - auto const_privKey = keys.getPrivateKey(); - auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES); - unsigned long long actualSignLength = 0; - - if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *const_privKey)) { - addError(new Error("User::sign 2", "sign failed")); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) { - // Incorrect signature! - //printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__); - addError(new Error("User::sign 2", "sign verify failed")); - mm->releaseMemory(privKey); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - return signBinBuffer; - } - - return nullptr; - } - - auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES); - - unsigned long long actualSignLength = 0; - - if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *privKey)) { - addError(new Error("User::sign", "sign failed")); - mm->releaseMemory(privKey); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) { - // Incorrect signature! - //printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__); - addError(new Error("User::sign", "sign verify failed")); - mm->releaseMemory(privKey); - mm->releaseMemory(signBinBuffer); - return nullptr; - } - - // debug - const size_t hex_sig_size = crypto_sign_BYTES * 2 + 1; - char sig_hex[hex_sig_size]; - sodium_bin2hex(sig_hex, hex_sig_size, *signBinBuffer, crypto_sign_BYTES); - printf("[User::sign] signature hex: %s\n", sig_hex); - - mm->releaseMemory(privKey); - - return signBinBuffer; -} - -Poco::Data::Statement User::insertIntoDB(Poco::Data::Session session) -{ - - Poco::Data::Statement insert(session); - - //Poco::Data::BLOB pwd(&mPasswordHashed[0], crypto_shorthash_BYTES); - - //printf("[User::insertIntoDB] password hashed: %llu\n", mPasswordHashed); - std::string languageKey = LanguageManager::keyForLanguage(mLanguage); - if (mPasswordHashed) { - insert << "INSERT INTO users (email, first_name, last_name, password, language) VALUES(?, ?, ?, ?, ?);", - use(mEmail), use(mFirstName), use(mLastName), bind(mPasswordHashed), bind(languageKey); - } - else { - insert << "INSERT INTO users (email, first_name, last_name, language) VALUES(?, ?, ?, ?);", - use(mEmail), use(mFirstName), use(mLastName), bind(languageKey); - } - - - return insert; -} - -bool User::updateIntoDB(UserFields fieldType) -{ - - if (mDBId == 0) { - addError(new Error("User::updateIntoDB", "user id is zero")); - return false; - } - if (USER_FIELDS_PASSWORD == fieldType || USER_FIELDS_EMAIL_CHECKED == fieldType) { - auto session = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); - Poco::Data::Statement update(session); - if (USER_FIELDS_PASSWORD == fieldType) { - update << "UPDATE users SET password = ? where id = ?", - use(mPasswordHashed), use(mDBId); - } - else if (USER_FIELDS_EMAIL_CHECKED == fieldType) { - update << "UPDATE users SET email_checked = ? where id = ?", - use(mEmailChecked), use(mDBId); - } - else if (USER_FIELDS_LANGUAGE == fieldType) { - std::string languageKey = LanguageManager::keyForLanguage(mLanguage); - update << "UPDATE users SET language = ? where id = ?", - bind(languageKey), use(mDBId); - } - try { - if (update.execute() == 1) return true; - addError(new ParamError("User::updateIntoDB", "update not affected 1 rows", fieldType)); - } - catch (Poco::Exception& ex) { - auto em = ErrorManager::getInstance(); - em->addError(new ParamError("User::updateIntoDB", "mysql error", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - } - - return false; - -} - -bool User::loadEntryDBId(Poco::Data::Session session) -{ - auto em = ErrorManager::getInstance(); - Poco::Data::Statement select(session); - - select << "SELECT id from users where email = ?;", - into(mDBId), use(mEmail); - try { - if (select.execute() != 1) { - addError(new Error("User::loadEntryDBId", "didn't get expectet row count (1)")); - return false; - } - } catch(Poco::Exception& ex) { - em->addError(new ParamError("[User::loadEntryDBId]", "error selecting from db", ex.displayText().data())); - em->sendErrorsAsEmail(); - } - - return true; -} - -const char* User::userStateToString(UserStates state) -{ - switch (state) { - case USER_EMPTY: return "empty"; - case USER_LOADED_FROM_DB: return "loaded from db"; - case USER_PASSWORD_INCORRECT: return "password incorrect"; - case USER_EMAIL_NOT_ACTIVATED: return "email not activated"; - case USER_NO_KEYS: return "no keys"; - case USER_NO_PRIVATE_KEY: return "no private key"; - case USER_COMPLETE: return "complete"; - } - return "- unknown -"; -} - -MemoryBin* User::getPrivKey() -{ - if (!mPrivateKey) { - addError(new Error("User::getPrivKey", "no private key saved")); - return nullptr; - } - if (!hasCryptoKey()) { - addError(new Error("User::getPrivKey", "no crypto key set for decrypting priv key")); - return nullptr; - } - return decrypt(mPrivateKey); -} - -bool User::setPrivKey(const MemoryBin* privKey) -{ - if (!hasCryptoKey()) { - lock("User::setPrivKey"); - addError(new Error("User::getPrivKey", "no crypto key set for encrypting priv key")); - unlock(); - return false; - } - auto encyrptedPrivKey = encrypt(privKey); - lock("User::setPrivKey"); - mState = USER_COMPLETE; - mPrivateKey = encyrptedPrivKey;// encrypt(privKey); - unlock(); - - return true; -} - -void User::lock(const char* stateInfos/* = nullptr*/) -{ - try { - mWorkingMutex.lock(500); - } - catch (Poco::TimeoutException& ex) { - addError(new ParamError("User::lock", "timeout exception", ex.displayText())); - if (stateInfos) { - addError(new ParamError("User::lock", "stateInfos", stateInfos)); - } - sendErrorsAsEmail(); - } -} \ No newline at end of file diff --git a/src/cpp/model/User.h b/src/cpp/model/User.h deleted file mode 100644 index cc1a8be86..000000000 --- a/src/cpp/model/User.h +++ /dev/null @@ -1,272 +0,0 @@ -#ifndef GRADIDO_LOGIN_SERVER_MODEL_USER_INCLUDE -#define GRADIDO_LOGIN_SERVER_MODEL_USER_INCLUDE - -#include "../Crypto/KeyPair.h" -#include -//#include "ModelBase.h" -#include "../lib/NotificationList.h" - -#include "Poco/Thread.h" -#include "Poco/Types.h" -#include "Poco/Data/Session.h" -#include "Poco/JSON/Object.h" -#include "../tasks/CPUTask.h" - -#include "../SingletonManager/MemoryManager.h" -#include "../SingletonManager/LanguageManager.h" - -#include "../controller/User.h" - -class UserCreateCryptoKey; -class UserWriteIntoDB; -class Session; -class UserWriteCryptoKeyHashIntoDB; -class SigningTransaction; -class UserGenerateKeys; -class DebugPassphrasePage; -class RepairDefectPassphrase; - -enum UserStates -{ - USER_EMPTY, - USER_LOADED_FROM_DB, - USER_PASSWORD_INCORRECT, - USER_PASSWORD_ENCRYPTION_IN_PROCESS, - USER_EMAIL_NOT_ACTIVATED, - USER_NO_KEYS, - USER_NO_PRIVATE_KEY, - USER_KEYS_DONT_MATCH, - USER_COMPLETE, - USER_DISABLED -}; - -enum UserFields -{ - USER_FIELDS_ID, - USER_FIELDS_FIRST_NAME, - USER_FIELDS_LAST_NAME, - USER_FIELDS_PASSWORD, - USER_FIELDS_EMAIL_CHECKED, - USER_FIELDS_LANGUAGE -}; - -class User : public NotificationList -{ - friend UserCreateCryptoKey; - friend UserWriteIntoDB; - friend UserWriteCryptoKeyHashIntoDB; - friend SigningTransaction; - friend UserGenerateKeys; - friend DebugPassphrasePage; - friend RepairDefectPassphrase; -public: - // new user - User(const char* email, const char* first_name, const char* last_name); - // existing user - User(const char* email); - - // existing user by public key - User(const unsigned char* pubkey_array); - - User(int user_id); - - // load from controller user - User(Poco::AutoPtr ctrl_user); - - // login - //User(const std::string& email, const std::string& password); - - ~User(); - - void login(Poco::AutoPtr newUser); - - static std::string generateNewPassphrase(Mnemonic* word_source); - static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr); - static const char* userStateToString(UserStates state); - //static User* login(const std::string& email, const std::string& password, ErrorList* errorContainer = nullptr); - - bool generateKeys(bool savePrivkey, const std::string& passphrase, Session* session); - - bool loadEntryDBId(Poco::Data::Session session); - - bool deleteFromDB(); - - inline bool hasCryptoKey() { lock(); bool bRet = mCryptoKey != nullptr; unlock(); return bRet; } - - inline const char* getEmail() const { return mEmail.data(); } - inline const char* getFirstName() const { return mFirstName.data(); } - inline const char* getLastName() const { return mLastName.data(); } - inline int getDBId() const { return mDBId; } - inline int getBalance() { lock(); int balance = mGradidoCurrentBalance; unlock(); return balance; } - inline std::string getPublicKeyHex() { lock(); std::string pubkeyHex = mPublicHex; unlock(); return pubkeyHex; } - inline const unsigned char* getPublicKey() { return mPublicKey; } - inline Languages getLanguage() { lock(); Languages lang = mLanguage; unlock(); return lang; } - - inline void setPublicKeyHex(const std::string& publicKeyHex) { lock(); mPublicHex = publicKeyHex; unlock(); } - inline void setPublicKey(const unsigned char* key) { lock(); memcpy(mPublicKey, key, crypto_sign_PUBLICKEYBYTES); unlock();} - - inline const char* gettext(const char* text) { if (mLanguageCatalog.isNull()) return text; return mLanguageCatalog->gettext(text); } - - UserStates getUserState(); - - void setLanguage(Languages lang); - inline void setBalance(int balance) { lock(); mGradidoCurrentBalance = balance; unlock(); } - void setEmailChecked(); - bool isEmptyPassword(); - //bool setNewPassword(const std::string& newPassword); - bool updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser); - bool validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint); - bool validateIdentHash(HASH hash); - - MemoryBin* encrypt(const MemoryBin* data); - MemoryBin* decrypt(const MemoryBin* encryptedData); - MemoryBin* sign(const unsigned char* message, size_t messageSize); - - Poco::JSON::Object getJson(); - - // for poco auto ptr - void duplicate(); - void release(); - - //! \brief wait time create crypto key is normally running - static void fakeCreateCryptoKey(); -protected: - typedef Poco::UInt64 passwordHashed; - - MemoryBin* createCryptoKey(const std::string& password); - static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver = nullptr); - inline void setCryptoKey(MemoryBin* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); } - - //void detectState(); - - Poco::Data::Statement insertIntoDB(Poco::Data::Session session); - bool updateIntoDB(UserFields fieldType); - inline passwordHashed getPwdHashed() { lock(); auto ret = mPasswordHashed; unlock(); return ret; } - inline void setPwdHashed(passwordHashed pwdHashed) { lock(); mPasswordHashed = pwdHashed; unlock(); } - - void lock(const char* stateInfos = nullptr); - inline void unlock() { mWorkingMutex.unlock(); } - - MemoryBin* getPrivKey(); - inline bool hasPrivKey() { lock(); bool result = false; if (mPrivateKey && mCryptoKey) result = true; unlock(); return result; } - bool setPrivKey(const MemoryBin* privKey); - -private: - Poco::AutoPtr mUserCtrl; - UserStates mState; - - // ************************* DB FIELDS ****************************** - int mDBId; - std::string mEmail; - std::string mFirstName; - std::string mLastName; - - passwordHashed mPasswordHashed; - - std::string mPublicHex; - unsigned char mPublicKey[crypto_sign_PUBLICKEYBYTES]; - //! crypted private key - MemoryBin* mPrivateKey; - // TODO: insert created if necessary - - bool mEmailChecked; - Languages mLanguage; - - // ************************ DB FIELDS END ****************************** - - int mGradidoCurrentBalance; - Poco::AutoPtr mLanguageCatalog; - - // crypto key as obfus array - // only in memory, if user has typed in password - MemoryBin* mCryptoKey; - - Poco::Mutex mWorkingMutex; - Poco::Mutex mReferenceMutex; - - // for poco auto ptr - int mReferenceCount; - - UniLib::controller::TaskPtr mCreateCryptoKeyTask; -}; - -class UserCreateCryptoKey : public UniLib::controller::CPUTask -{ -public: - UserCreateCryptoKey(Poco::AutoPtr user, Poco::AutoPtr newUser, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler); - - virtual int run(); - virtual const char* getResourceType() const { return "UserCreateCryptoKey"; }; - -private: - Poco::AutoPtr mUser; - Poco::AutoPtr mNewUser; - std::string mPassword; -}; - -class UserGenerateKeys : public UniLib::controller::CPUTask -{ -public: - UserGenerateKeys(Poco::AutoPtr user, Poco::AutoPtr newUser, const std::string& passphrase) - : mUser(user), mNewUser(newUser), mPassphrase(passphrase) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - ~UserGenerateKeys() { - - } - virtual int run(); - inline KeyPair* getKeyPairs() { return &mKeys; } - - virtual const char* getResourceType() const { return "UserGenerateKeys"; }; -protected: - Poco::AutoPtr mUser; - Poco::AutoPtr mNewUser; - std::string mPassphrase; - KeyPair mKeys; -}; - -class UserWriteIntoDB : public UniLib::controller::CPUTask -{ -public: - UserWriteIntoDB(Poco::AutoPtr user, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) - : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - virtual int run(); - virtual const char* getResourceType() const { return "UserWriteIntoDB"; }; -private: - Poco::AutoPtr mUser; -}; - -class UserWriteKeysIntoDB : public UniLib::controller::CPUTask -{ -public: - UserWriteKeysIntoDB(std::vector parents, Poco::AutoPtr user, bool savePrivKey); - - virtual int run(); - - virtual const char* getResourceType() const { return "UserWriteKeysIntoDB"; }; -protected: - Poco::AutoPtr mUser; - bool mSavePrivKey; -}; - -class UserWriteCryptoKeyHashIntoDB : public UniLib::controller::CPUTask -{ -public: - UserWriteCryptoKeyHashIntoDB(Poco::AutoPtr user, int dependencieCount = 0); - - int run(); - const char* getResourceType() const { return "UserWriteCryptoKeyHashIntoDB"; }; - -protected: - Poco::AutoPtr mUser; -}; - -#endif //GRADIDO_LOGIN_SERVER_MODEL_USER_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index 11584659c..d45147532 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -17,8 +17,8 @@ namespace model { { } - User::User(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) - : mFirstName(first_name), mLastName(last_name), mPasswordHashed(passwordHashed), mEmailChecked(false), mLanguageKey(languageKey), mDisabled(false), mRole(ROLE_NOT_LOADED) + User::User(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) + : mFirstName(first_name), mLastName(last_name), mPasswordHashed(passwordHashed), mEmailChecked(false), mLanguageKey(languageKey), mDisabled(false), mGroupId(group_id), mRole(ROLE_NOT_LOADED) { setEmail(email); @@ -27,7 +27,7 @@ namespace model { User::User(UserTuple tuple) : ModelBase(tuple.get<0>()), mFirstName(tuple.get<1>()), mLastName(tuple.get<2>()), mEmail(tuple.get<3>()), - mPublicKey(tuple.get<4>()), mCreated(tuple.get<5>()), mEmailChecked(tuple.get<6>()), mDisabled(tuple.get<7>()), + mPublicKey(tuple.get<4>()), mCreated(tuple.get<5>()), mEmailChecked(tuple.get<6>()), mDisabled(tuple.get<7>()), mGroupId(tuple.get<8>()), mPasswordHashed(0), mLanguageKey("de"), mRole(ROLE_NOT_LOADED) { @@ -80,12 +80,12 @@ namespace model { if (mPasswordHashed) { - insert << "INSERT INTO users (email, first_name, last_name, password, email_hash, language) VALUES(?,?,?,?,?,?);", - use(mEmail), use(mFirstName), use(mLastName), bind(mPasswordHashed), use(mEmailHash), use(mLanguageKey); + insert << "INSERT INTO users (email, first_name, last_name, password, email_hash, language, group_id) VALUES(?,?,?,?,?,?,?);", + use(mEmail), use(mFirstName), use(mLastName), bind(mPasswordHashed), use(mEmailHash), use(mLanguageKey), use(mGroupId); } else { - insert << "INSERT INTO users (email, first_name, last_name, email_hash, language) VALUES(?,?,?,?,?);", - use(mEmail), use(mFirstName), use(mLastName), use(mEmailHash), use(mLanguageKey); + insert << "INSERT INTO users (email, first_name, last_name, email_hash, language, group_id) VALUES(?,?,?,?,?,?);", + use(mEmail), use(mFirstName), use(mLastName), use(mEmailHash), use(mLanguageKey), use(mGroupId); } return insert; @@ -98,13 +98,13 @@ namespace model { _fieldName = getTableName() + std::string(".id"); } Poco::Data::Statement select(session); - select << "SELECT " << getTableName() << ".id, email, first_name, last_name, password, pubkey, privkey, email_hash, created, email_checked, language, disabled, user_roles.role_id " + select << "SELECT " << getTableName() << ".id, email, first_name, last_name, password, pubkey, privkey, email_hash, created, email_checked, language, disabled, group_id, user_roles.role_id " << " FROM " << getTableName() << " LEFT JOIN user_roles ON " << getTableName() << ".id = user_roles.user_id " << " WHERE " << _fieldName << " = ?" , into(mID), into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(mPublicKey), into(mPrivateKey), into(mEmailHash), into(mCreated), into(mEmailChecked), - into(mLanguageKey), into(mDisabled), into(mRole); + into(mLanguageKey), into(mDisabled), into(mGroupId), into(mRole); return select; @@ -114,7 +114,7 @@ namespace model { { Poco::Data::Statement select(session); // typedef Poco::Tuple, int> UserTuple; - select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled FROM " << getTableName() + select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled, group_id FROM " << getTableName() << " where " << fieldName << " LIKE ?"; @@ -130,7 +130,7 @@ namespace model { } // typedef Poco::Tuple, int> UserTuple; - select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled FROM " << getTableName() + select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled, group_id FROM " << getTableName() << " where " << fieldNames[0] << " LIKE ?"; if (conditionType == MYSQL_CONDITION_AND) { for (int i = 1; i < fieldNames.size(); i++) { @@ -311,6 +311,7 @@ namespace model { ss << "email checked: " << mEmailChecked << std::endl; ss << "language key: " << mLanguageKey << std::endl; ss << "disabled: " << mDisabled << std::endl; + ss << "group id: " << std::to_string(mGroupId) << std::endl; mm->releaseMemory(pubkeyHex); mm->releaseMemory(privkeyHex); @@ -346,6 +347,7 @@ namespace model { ss << "language key: " << mLanguageKey << "
    "; ss << "role: " << UserRole::typeToString(getRole()) << "
    "; ss << "disabled: " << mDisabled << "
    "; + ss << "group_id: " << std::to_string(mGroupId) << std::endl; mm->releaseMemory(pubkeyHex); mm->releaseMemory(email_hash); @@ -369,6 +371,25 @@ namespace model { return pubkeyHexString; } + std::string User::getPrivateKeyEncryptedHex() const + { + std::shared_lock _lock(mSharedMutex); + auto mm = MemoryManager::getInstance(); + std::string privkeyHexString; + + if (!mPrivateKey.isNull()) { + auto priv_key_size = mPrivateKey.value().content().size(); + auto privkeyHex = mm->getFreeMemory(priv_key_size+1); + + memset(*privkeyHex, 0, priv_key_size+1); + sodium_bin2hex(*privkeyHex, 65, mPrivateKey.value().content().data(), priv_key_size); + privkeyHexString = std::string((const char*)privkeyHex->data(), privkeyHex->size() - 1); + mm->releaseMemory(privkeyHex); + } + + return privkeyHexString; + } + Poco::JSON::Object User::getJson() { diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index d7523d155..8733457f5 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -29,14 +29,16 @@ namespace model { USER_FIELDS_LANGUAGE }; - typedef Poco::Tuple, Poco::DateTime, int, int> UserTuple; + typedef Poco::Tuple, Poco::DateTime, int, int, int> UserTuple; class User : public ModelBase { public: +#define SHARED_LOCK std::shared_lock _lock(mSharedMutex) +#define UNIQUE_LOCK std::unique_lock _lock(mSharedMutex) User(); User(UserTuple tuple); - User(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); + User(const std::string& email, const std::string& first_name, const std::string& last_name, int group_id, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); ~User(); // generic db operations @@ -54,36 +56,39 @@ namespace model { size_t updateFieldsFromCommunityServer(); // default getter unlocked - inline const std::string getEmail() const { std::shared_lock _lock(mSharedMutex); return mEmail; } - inline const std::string getFirstName() const { std::shared_lock _lock(mSharedMutex); return mFirstName; } - inline const std::string getLastName() const { std::shared_lock _lock(mSharedMutex); return mLastName; } - inline std::string getNameWithEmailHtml() const { std::shared_lock _lock(mSharedMutex); return mFirstName + " " + mLastName + " <" + mEmail + ">"; } - inline std::string getNameWithEmail() const { std::shared_lock _lock(mSharedMutex); return mFirstName + " " + mLastName + "<" + mEmail + ">"; } - inline const Poco::UInt64 getPasswordHashed() const { std::shared_lock _lock(mSharedMutex); return mPasswordHashed; } - inline RoleType getRole() const { std::shared_lock _lock(mSharedMutex); if (mRole.isNull()) return ROLE_NONE; return static_cast(mRole.value()); } - inline const unsigned char* getPublicKey() const { std::shared_lock _lock(mSharedMutex); if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } - inline size_t getPublicKeySize() const { std::shared_lock _lock(mSharedMutex); if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } - std::string getPublicKeyHex() const; - inline bool hasPrivateKeyEncrypted() const { std::shared_lock _lock(mSharedMutex); return !mPrivateKey.isNull(); } - inline bool hasEmailHash() const { std::shared_lock _lock(mSharedMutex); return !mEmailHash.isNull(); } - inline const std::vector& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); } - inline bool isEmailChecked() const { std::shared_lock _lock(mSharedMutex); return mEmailChecked; } - inline const std::string getLanguageKey() const { std::shared_lock _lock(mSharedMutex); return mLanguageKey; } - inline bool isDisabled() const { std::shared_lock _lock(mSharedMutex); return mDisabled; } + inline const std::string getEmail() const { SHARED_LOCK; return mEmail; } + inline const std::string getFirstName() const { SHARED_LOCK; return mFirstName; } + inline const std::string getLastName() const { SHARED_LOCK; return mLastName; } + inline std::string getNameWithEmailHtml() const { SHARED_LOCK; return mFirstName + " " + mLastName + " <" + mEmail + ">"; } + inline const Poco::UInt64 getPasswordHashed() const { SHARED_LOCK; return mPasswordHashed; } + inline RoleType getRole() const { SHARED_LOCK; if (mRole.isNull()) return ROLE_NONE; return static_cast(mRole.value()); } + inline const unsigned char* getPublicKey() const { SHARED_LOCK; if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + inline size_t getPublicKeySize() const { SHARED_LOCK; if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); } + std::string getPublicKeyHex() const; + std::string getPrivateKeyEncryptedHex() const; + + inline bool hasPrivateKeyEncrypted() const { SHARED_LOCK; return !mPrivateKey.isNull(); } + inline bool hasPublicKey() const { SHARED_LOCK; return !mPublicKey.isNull(); } + inline bool hasEmailHash() const { SHARED_LOCK; return !mEmailHash.isNull(); } + inline const std::vector& getPrivateKeyEncrypted() const { SHARED_LOCK; return mPrivateKey.value().content(); } + inline bool isEmailChecked() const { SHARED_LOCK; return mEmailChecked; } + inline const std::string getLanguageKey() const { SHARED_LOCK; return mLanguageKey; } + inline bool isDisabled() const { SHARED_LOCK; return mDisabled; } + inline int getGroupId() const { SHARED_LOCK; return mGroupId; } // default setter unlocked void setEmail(const std::string& email); - inline void setFirstName(const std::string& first_name) { std::unique_lock _lock(mSharedMutex); mFirstName = first_name; } - inline void setLastName(const std::string& last_name) { std::unique_lock _lock(mSharedMutex); mLastName = last_name; } - inline void setPasswordHashed(const Poco::UInt64& passwordHashed) { std::unique_lock _lock(mSharedMutex); mPasswordHashed = passwordHashed; } + inline void setFirstName(const std::string& first_name) { UNIQUE_LOCK; mFirstName = first_name; } + inline void setLastName(const std::string& last_name) { UNIQUE_LOCK; mLastName = last_name; } + inline void setPasswordHashed(const Poco::UInt64& passwordHashed) { UNIQUE_LOCK; mPasswordHashed = passwordHashed; } void setPublicKey(const unsigned char* publicKey); //! \brief set encrypted private key //! \param privateKey copy data, didn't move memory bin void setPrivateKey(const MemoryBin* privateKey); - inline void setEmailChecked(bool emailChecked) { std::unique_lock _lock(mSharedMutex); mEmailChecked = emailChecked; } - inline void setLanguageKey(const std::string& languageKey) { std::unique_lock _lock(mSharedMutex); mLanguageKey = languageKey; } - inline void setDisabled(bool disabled) { std::unique_lock _lock(mSharedMutex); mDisabled = disabled; } + inline void setEmailChecked(bool emailChecked) { UNIQUE_LOCK; mEmailChecked = emailChecked; } + inline void setLanguageKey(const std::string& languageKey) { UNIQUE_LOCK; mLanguageKey = languageKey; } + inline void setDisabled(bool disabled) { UNIQUE_LOCK; mDisabled = disabled; } Poco::JSON::Object getJson(); @@ -114,6 +119,8 @@ namespace model { //! if set to true, prevent login bool mDisabled; + int mGroupId; + // from neighbor tables Poco::Nullable mRole; diff --git a/src/cpp/tasks/SigningTransaction.h b/src/cpp/tasks/SigningTransaction.h index 60f9c65c1..ecbcb08e4 100644 --- a/src/cpp/tasks/SigningTransaction.h +++ b/src/cpp/tasks/SigningTransaction.h @@ -5,7 +5,6 @@ #include "../lib/NotificationList.h" #include "../model/TransactionBase.h" -#include "../model/User.h" #include "../controller/User.h" #include "../proto/gradido/GradidoTransaction.pb.h" diff --git a/src/cpsp/Error500.cpsp b/src/cpsp/Error500.cpsp index 7cea4f563..0cc255eed 100644 --- a/src/cpsp/Error500.cpsp +++ b/src/cpsp/Error500.cpsp @@ -10,18 +10,18 @@ <% const char* pageName = "Error"; response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR); - Poco::AutoPtr user; + Poco::AutoPtr user; if(mSession) { - auto user = mSession->getUser(); + auto user = mSession->getNewUser(); } %><%@ include file="header_old.cpsp" %>

    Ein Fehler auf dem Server trat ein, der Admin bekam eine E-Mail.

    <% if(mSession) { %> - <%= mSession->getErrorsHtml() %> + <%= mSession->getErrorsHtmlNewFormat() %> <% } %> <% if(!user.isNull()) {%> - <%= user->getErrorsHtml() %> + <%= user->getModel()->getErrorsHtmlNewFormat() %> <% } %>
    <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/PassphrasedTransaction.cpsp b/src/cpsp/PassphrasedTransaction.cpsp index debc1f296..8c360da79 100644 --- a/src/cpsp/PassphrasedTransaction.cpsp +++ b/src/cpsp/PassphrasedTransaction.cpsp @@ -6,7 +6,7 @@ <%! #include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/SessionManager.h" -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" #include "Poco/JSON/Object.h" @@ -23,29 +23,28 @@ enum PageState { <%% std::string pageName = "Gradidos mit Passphrase überweisen"; PageState state = PAGE_STATE_INPUT; - Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]; + Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES]; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); std::string errorString =""; if(!form.empty()) { auto passphrase = form.get("passphrase", ""); - bool passphraseValid = User::validatePassphrase(passphrase, &wordSource); + auto passphrase_obj = Passphrase::create(passphrase, wordSource); + bool keysGenerated = false; - KeyPair keys; - if(!passphraseValid) - { + KeyPairEd25519* keys = nullptr; + if(!passphrase_obj.isNull()) { addError(new Error("Passphrase", "Fehler beim validieren der Passphrase")); } - else - { - keysGenerated = keys.generateFromPassphrase(passphrase.data(), wordSource); - if(!keysGenerated) + else { + keys = KeyPairEd25519::create(passphrase_obj); + if(!keys) { addError(new Error("Passphrase", "Konnte keine Keys aus der Passphrase generieren")); } } - if(passphraseValid && keysGenerated) + if(keys) { // create session only for transaction int session_id = 0; @@ -53,7 +52,7 @@ enum PageState { // create payload Poco::JSON::Object requestJson; Poco::JSON::Object pubkeys; - pubkeys.set("sender", keys.getPubkeyHex()); + pubkeys.set("sender", keys->getPublicKeyHex()); pubkeys.set("receiver", form.get("recevier", "")); requestJson.set("method", "moveTransaction"); requestJson.set("pubkeys", pubkeys); @@ -129,6 +128,8 @@ enum PageState { if(session) { sm->releaseSession(session); } + delete keys; + keys = nullptr; } } diff --git a/src/cpsp/adminCheckUserBackup.cpsp b/src/cpsp/adminCheckUserBackup.cpsp index 35ac38ad4..66156796d 100644 --- a/src/cpsp/adminCheckUserBackup.cpsp +++ b/src/cpsp/adminCheckUserBackup.cpsp @@ -5,10 +5,11 @@ <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> <%! -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" +#include "../Crypto/Passphrase.h" #include "../SingletonManager/ConnectionManager.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "Poco/Data/Binding.h" using namespace Poco::Data::Keywords; @@ -25,7 +26,7 @@ struct SListEntry <%% const char* pageName = "Admin Check User Backups"; auto cm = ConnectionManager::getInstance(); - KeyPair keys; + std::list notMatchingEntrys; auto con = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); @@ -44,21 +45,24 @@ struct SListEntry if(pubkey.isNull()) { continue; } - auto passphrase = KeyPair::filterPassphrase(tuple.get<2>()); + auto passphrase = Passphrase::filter(tuple.get<2>()); auto user_id = tuple.get<0>(); - Mnemonic* wordSource = nullptr; - if(!User::validatePassphrase(passphrase, &wordSource)) { + KeyPairEd25519 key_pair(pubkey.value().content().data()); + + auto wordSource = Passphrase::detectMnemonic(passphrase); + if(!wordSource) { addError(new Error("admin Check user backup", "invalid passphrase"), false); addError(new ParamError("admin Check user backup", "passphrase", passphrase.data()), false); addError(new ParamError("admin Check user backup", "user id", user_id), false); continue; - } else { - keys.generateFromPassphrase(passphrase.data(), wordSource); - } + } + auto passphrase_object = Passphrase::create(passphrase, wordSource); + auto key_pair_from_passhrase = KeyPairEd25519::create(passphrase_object); bool matching = false; - if(keys.isPubkeysTheSame(pubkey.value().content().data())) { + if(key_pair_from_passhrase->isTheSame(key_pair)) { matching = true; } + delete key_pair_from_passhrase; if(user_id != last_user_id) { last_user_id = user_id; if(matching) continue; diff --git a/src/cpsp/adminUserPasswordReset.cpsp b/src/cpsp/adminUserPasswordReset.cpsp index f534b8c4d..7022b42d9 100644 --- a/src/cpsp/adminUserPasswordReset.cpsp +++ b/src/cpsp/adminUserPasswordReset.cpsp @@ -8,7 +8,7 @@ // includes #include "../controller/User.h" #include "../controller/EmailVerificationCode.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" enum PageState @@ -47,11 +47,11 @@ enum PageState } } - auto backups = controller::UserBackups::load(userId); + auto backups = controller::UserBackup::load(userId); auto userPubkey = user->getModel()->getPublicKey(); for(auto it = backups.begin(); it != backups.end(); it++) { auto keys = (*it)->getKeyPair(); - if(keys->isPubkeysTheSame(userPubkey)) { + if(keys->isTheSame(userPubkey)) { userBackup = *it; break; } @@ -102,7 +102,7 @@ enum PageState hier findest du deine Passphrase mit dessen Hilfe du dir ein neues Passwort einstellen kannst. Bitte schreibe sie dir auf und packe sie gut weg. -<%= controller::UserBackups::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) %> +<%= controller::UserBackup::formatPassphrase(userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER)) %> diff --git a/src/cpsp/checkTransaction.cpsp b/src/cpsp/checkTransaction.cpsp index 660eb08bd..cfe21118c 100644 --- a/src/cpsp/checkTransaction.cpsp +++ b/src/cpsp/checkTransaction.cpsp @@ -192,8 +192,10 @@ enum PageState { <%= gettext("Gradido") %>
    - <% if(transactionUser) { %> - <%= transactionUser->getFirstName() %> <%= transactionUser->getLastName() %> <<%= transactionUser->getEmail() %>> + <% if(!transactionUser.isNull()) { + auto user_model = transactionUser->getModel(); + %> + <%= user_model->getFirstName() %> <%= user_model->getLastName() %> <<%= user_model->getEmail() %>> <% } else { %> 0x<%= creationTransaction->getPublicHex() %> <% } %> diff --git a/src/cpsp/dashboard.cpsp b/src/cpsp/dashboard.cpsp index 687c6a709..654f7a4c3 100644 --- a/src/cpsp/dashboard.cpsp +++ b/src/cpsp/dashboard.cpsp @@ -10,6 +10,8 @@ %> <%% const char* pageName = "Dashboard"; + auto user = mSession->getNewUser(); + auto user_model = user->getModel(); //Poco::Net::NameValueCollection cookies; //request.getCookies(cookies); if(!form.empty()) { @@ -20,7 +22,7 @@ return; %><%@ include file="header_old.cpsp" %>
    -

    Willkommen <%= mSession->getUser()->getFirstName() %> <%= mSession->getUser()->getLastName() %>

    +

    Willkommen <%= user_model->getFirstName() %> <%= user_model->getLastName() %>

    <%= mSession->getErrorsHtml() %>

    Status

    <%= mSession->getSessionStateString() %>

    diff --git a/src/cpsp/debugMnemonic.cpsp b/src/cpsp/debugMnemonic.cpsp index 06f0c5f86..aa52d4561 100644 --- a/src/cpsp/debugMnemonic.cpsp +++ b/src/cpsp/debugMnemonic.cpsp @@ -6,7 +6,7 @@ <%@ header include="SessionHTTPRequestHandler.h" %> <%! #include "../ServerConfig.h" -#include "../Crypto/KeyPair.h" +#include "../Crypto/Passphrase.h" struct WordChecked { WordChecked() : index(0), bSet(false) {}; @@ -48,7 +48,7 @@ { if("" != form.get("check_word", "")) { - auto word = KeyPair::filterPassphrase(form.get("word", "")); + auto word = Passphrase::filter(form.get("word", "")); if("" != word) { checkedWord.bSet = true; checkedWord.word = word; diff --git a/src/cpsp/debugPassphrase.cpsp b/src/cpsp/debugPassphrase.cpsp index 936a4629f..416bdf0a3 100644 --- a/src/cpsp/debugPassphrase.cpsp +++ b/src/cpsp/debugPassphrase.cpsp @@ -5,45 +5,36 @@ <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> <%! -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" +#include "../controller/User.h" %> <%% const char* pageName = "Debug Passphrase"; - auto mm = MemoryManager::getInstance(); - KeyPair keys; - std::string privKeyHex = ""; + + KeyPairEd25519* keys = nullptr; std::string privKeyCryptedHex = ""; - User::passwordHashed pwdHashed = 0; + Poco::UInt64 pwdHashed = 0; Poco::AutoPtr existingUser; if(!form.empty()) { - auto passphrase = KeyPair::filterPassphrase(form.get("passphrase", "")); - Mnemonic* wordSource = nullptr; - if(!User::validatePassphrase(passphrase, &wordSource)) { + auto passphrase_string = form.get("passphrase", ""); + auto wordSource = Passphrase::detectMnemonic(passphrase_string); + if(!wordSource) { addError(new Error("debug Passphrase", "invalid passphrase"), false); } else { - keys.generateFromPassphrase(passphrase.data(), wordSource); + keys = KeyPairEd25519::create(Passphrase::create(passphrase_string, wordSource)); } auto email = form.get("email", ""); - auto newUser = new User(email.data(), "first_name", "last_name"); - if(email != "") { existingUser = controller::User::create(); - existingUser->load(email); - } - newUser->validatePwd(form.get("password", ""), this); - pwdHashed = newUser->getPwdHashed(); - auto privKey = keys.getPrivateKey(); - if(privKey) { - privKeyHex = KeyPair::getHex(privKey); - auto privKeyCrypted = newUser->encrypt(privKey); - if(privKeyCrypted) { - privKeyCryptedHex = KeyPair::getHex(privKeyCrypted); - mm->releaseMemory(privKeyCrypted); + if(1 == existingUser->load(email)) { + auto user_model = existingUser->getModel(); + pwdHashed = user_model->getPasswordHashed(); + if(user_model->hasPrivateKeyEncrypted()) { + privKeyCryptedHex = user_model->getPrivateKeyEncryptedHex(); + } } } - getErrors(newUser); - delete newUser; } @@ -58,23 +49,21 @@ "/>

    -

    - - -

    -

    Public key:
    <%= keys.getPubkeyHex() %>

    -

    Private Key:
    <%= privKeyHex %>

    -

    Passwort Hashed:
    <%= std::to_string(pwdHashed) %>

    -

    Private key crypted:
    <%= privKeyCryptedHex %>

    - <% if(!existingUser.isNull()) { - auto userModel = existingUser->getModel(); - auto dbPubkey = userModel->getPublicKey(); - %> -

    user Public:
    <%= KeyPair::getHex(dbPubkey, ed25519_pubkey_SIZE) %>

    + <% if(keys) { %> +

    Public key:
    <%= keys->getPublicKeyHex() %>

    +

    Private key crypted:
    <%= privKeyCryptedHex %>

    +

    Passwort Hashed:
    <%= std::to_string(pwdHashed) %>

    + <% if(!existingUser.isNull()) { + auto userModel = existingUser->getModel(); + auto dbPubkey = userModel->getPublicKey(); + %> +

    user Public:
    <%= keys->getPublicKeyHex() %>

    + <% } %> <% } %>
    +<% if(keys) delete keys; %> <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index eca27299d..0f2a4d281 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -1,205 +1,211 @@ -<%@ page class="LoginPage" %> -<%@ page form="true" %> -<%@ page baseClass="SessionHTTPRequestHandler" %> -<%@ page ctorArg="Session*" %> -<%@ header include="SessionHTTPRequestHandler.h" %> -<%@ page compressed="true" %> -<%! -#include "../gettext.h" - -#include "Poco/Net/HTTPCookie.h" -#include "Poco/Net/HTTPServerParams.h" -#include "Poco/Logger.h" -#include "../SingletonManager/SessionManager.h" -#include "../SingletonManager/LanguageManager.h" -#include "../SingletonManager/ErrorManager.h" - -%> -<%% - const char* pageName = "Login"; - auto sm = SessionManager::getInstance(); - auto lm = LanguageManager::getInstance(); - auto em = ErrorManager::getInstance(); - - auto lang = chooseLanguage(request); - //printf("choose language return: %d\n", lang); - auto langCatalog = lm->getFreeCatalog(lang); - - std::string presetEmail(""); - if(mSession && mSession->getUser()) { - presetEmail = mSession->getUser()->getEmail(); - } - - if(!form.empty()) { - - bool langUpdatedByBtn = false; - auto langBtn = form.get("lang", ""); - if(langBtn != "") { - langUpdatedByBtn = true; - } - /* - auto langInput = form.get("lang", ""); - auto updatedLang = LANG_NULL; - if(langBtn != "") { - updatedLang = chooseLanguage(request, langBtn); - langUpdatedByBtn = true; - } else if(langInput != "") { - updatedLang = chooseLanguage(request, langInput); - } - - if(updatedLang != LANG_NULL && updatedLang != lang) { - lang = updatedLang; - langCatalog = lm->getFreeCatalog(lang); - } - */ - auto email = form.get("login-email", ""); - auto password = form.get("login-password", ""); - - if(email != "" && password != "") { - //auto session = sm->getSession(request); - //if(!mSession) mSession = sm->findByEmail(email); - if(!mSession) { - mSession = sm->getNewSession(); - mSession->setLanguageCatalog(langCatalog); - // get language - // first check url, second check language header - // for debugging client ip - auto client_host = request.clientAddress().host(); - //auto client_ip = request.clientAddress(); - // X-Real-IP forwarded ip from nginx config - auto client_host_string = request.get("X-Real-IP", client_host.toString()); - std::string clientIpString = "client ip: "; - client_host = Poco::Net::IPAddress(client_host_string); - clientIpString += client_host_string; - Poco::Logger::get("requestLog").information(clientIpString); - // debugging end - mSession->setClientIp(client_host); - response.addCookie(mSession->getLoginCookie()); - } else { - langCatalog = mSession->getLanguageCatalog(); - } - UserStates user_state; - try { - user_state = mSession->loadUser(email, password); - } catch (Poco::Exception& ex) { - addError(new ParamError("login", "exception by calling loadUser: ", ex.displayText())); - sendErrorsAsEmail(); - addError(new Error("Error", "Intern Server error, please try again later")); - } - auto user = mSession->getNewUser(); - - if(user_state >= USER_LOADED_FROM_DB && !user->getModel()->getPublicKey()) { - if(mSession->generateKeys(true, true)) { - user_state = USER_COMPLETE; - if(user->getModel()->isDisabled()) { - user_state = USER_DISABLED; - } - } - } else { - //printf("pubkey exist: %p\n",user->getModel()->getPublicKey()); - } - getErrors(mSession); - - auto uri_start = request.serverParams().getServerName(); - auto lastExternReferer = mSession->getLastReferer(); - - printf("user_state: %d\n", user_state); - - switch(user_state) { - case USER_EMPTY: - case USER_PASSWORD_INCORRECT: - addError(new Error(langCatalog->gettext("Login"), langCatalog->gettext("E-Mail or password isn't right, please try again!")), false); - if(mSession) { - getErrors(mSession); - sm->releaseSession(mSession); - } - sm->deleteLoginCookies(request, response); - break; - case USER_PASSWORD_ENCRYPTION_IN_PROCESS: - addError(new Error(langCatalog->gettext("Passwort"), langCatalog->gettext("Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut.")), false); - break; - case USER_KEYS_DONT_MATCH: - addError(new Error(langCatalog->gettext("User"), langCatalog->gettext("Error in saved data, the server admin will look at it."))); - break; - case USER_DISABLED: - addError(new Error(langCatalog->gettext("User"), langCatalog->gettext("Benutzer ist deaktiviert, kein Login möglich!"))); - if(mSession) { - getErrors(mSession); - sm->releaseSession(mSession); - } - sm->deleteLoginCookies(request, response); - break; - case USER_NO_PRIVATE_KEY: - case USER_COMPLETE: - case USER_EMAIL_NOT_ACTIVATED: - auto referer = request.find("Referer"); - std::string refererString; - if (referer != request.end()) { - refererString = referer->second; - } - if(lastExternReferer != "") { - //printf("redirect to: %s\n", lastExternReferer.data()); - response.redirect(lastExternReferer); - } else if(refererString != "" && - refererString.find("login") == std::string::npos && - refererString.find("logout") == std::string::npos && - refererString.find("user_delete") == std::string::npos && - refererString != ServerConfig::g_serverPath + request.getURI()) { - std::string uri = request.getURI(); - printf("request uri: %s, redirect to: %s\n", uri.data(), refererString.data()); - response.redirect(refererString); - } else { - //printf("redirect to: %s\n", ServerConfig::g_php_serverPath.data()); - response.redirect(ServerConfig::g_php_serverPath + "/"); - } - return; - } - - } else if(!langUpdatedByBtn) { - addError(new Error(langCatalog->gettext("Login"), langCatalog->gettext("Username and password are needed!")), false); - } - - } else { - - // on enter login page with empty form - //auto session = sm->getSession(request); - // remove old cookies and session if exist - if(mSession) { - getErrors(mSession); - sm->releaseSession(mSession); - } - sm->deleteLoginCookies(request, response); - } - -%><%@ include file="header.cpsp" %> -<%= getErrorsHtml() %> - -
    - <%@ include file="flags.cpsp" %> -
    -
    - " value="<%= presetEmail %>"/> - " /> - -
    -
    -
    - - -
    -
    -

     

    - +<%@ page class="LoginPage" %> +<%@ page form="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%@ page compressed="true" %> +<%! +#include "../gettext.h" + +#include "Poco/Net/HTTPCookie.h" +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Logger.h" +#include "../SingletonManager/SessionManager.h" +#include "../SingletonManager/LanguageManager.h" +#include "../SingletonManager/ErrorManager.h" + +%> +<%% + const char* pageName = "Login"; + auto sm = SessionManager::getInstance(); + auto lm = LanguageManager::getInstance(); + auto em = ErrorManager::getInstance(); + + auto lang = chooseLanguage(request); + //printf("choose language return: %d\n", lang); + auto langCatalog = lm->getFreeCatalog(lang); + + std::string presetEmail(""); + if(mSession && mSession->getUser()) { + presetEmail = mSession->getUser()->getEmail(); + } + + if(!form.empty()) { + + bool langUpdatedByBtn = false; + auto langBtn = form.get("lang", ""); + if(langBtn != "") { + langUpdatedByBtn = true; + } + /* + auto langInput = form.get("lang", ""); + auto updatedLang = LANG_NULL; + if(langBtn != "") { + updatedLang = chooseLanguage(request, langBtn); + langUpdatedByBtn = true; + } else if(langInput != "") { + updatedLang = chooseLanguage(request, langInput); + } + + if(updatedLang != LANG_NULL && updatedLang != lang) { + lang = updatedLang; + langCatalog = lm->getFreeCatalog(lang); + } + */ + auto email = form.get("login-email", ""); + auto password = form.get("login-password", ""); + + if(email != "" && password != "") { + //auto session = sm->getSession(request); + //if(!mSession) mSession = sm->findByEmail(email); + if(!mSession) { + mSession = sm->getNewSession(); + mSession->setLanguageCatalog(langCatalog); + // get language + // first check url, second check language header + // for debugging client ip + auto client_host = request.clientAddress().host(); + //auto client_ip = request.clientAddress(); + // X-Real-IP forwarded ip from nginx config + auto client_host_string = request.get("X-Real-IP", client_host.toString()); + std::string clientIpString = "client ip: "; + client_host = Poco::Net::IPAddress(client_host_string); + clientIpString += client_ip.toString(); + // clientIpString += client_host_string; + Poco::Logger::get("requestLog").information(clientIpString); + // debugging end + auto user_host = request.clientAddress().host(); + mSession->setClientIp(user_host); + // mSession->setClientIp(client_host); + response.addCookie(mSession->getLoginCookie()); + } else { + langCatalog = mSession->getLanguageCatalog(); + } + UserStates user_state; + try { + user_state = mSession->loadUser(email, password); + } catch (Poco::Exception& ex) { + addError(new ParamError("login", "exception by calling loadUser: ", ex.displayText())); + sendErrorsAsEmail(); + addError(new Error("Error", "Intern Server error, please try again later")); + } + auto user = mSession->getNewUser(); + + if(user_state >= USER_LOADED_FROM_DB && !user->getModel()->getPublicKey()) { + if(mSession->generateKeys(true, true)) { + user_state = USER_COMPLETE; + if(user->getModel()->isDisabled()) { + user_state = USER_DISABLED; + } + } + } else { + //printf("pubkey exist: %p\n",user->getModel()->getPublicKey()); + } + getErrors(mSession); + + auto uri_start = request.serverParams().getServerName(); + auto lastExternReferer = mSession->getLastReferer(); + + printf("user_state: %d\n", user_state); + + switch(user_state) { + case USER_EMPTY: + case USER_PASSWORD_INCORRECT: + addError(new Error(langCatalog->gettext("Login"), langCatalog->gettext("E-Mail or password isn't right, please try again!")), false); + if(mSession) { + getErrors(mSession); + sm->releaseSession(mSession); + } + sm->deleteLoginCookies(request, response); + break; + case USER_PASSWORD_ENCRYPTION_IN_PROCESS: + addError(new Error(langCatalog->gettext("Passwort"), langCatalog->gettext("Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut.")), false); + break; + case USER_KEYS_DONT_MATCH: + addError(new Error(langCatalog->gettext("User"), langCatalog->gettext("Error in saved data, the server admin will look at it."))); + break; + case USER_DISABLED: + addError(new Error(langCatalog->gettext("User"), langCatalog->gettext("Benutzer ist deaktiviert, kein Login möglich!"))); + if(mSession) { + getErrors(mSession); + sm->releaseSession(mSession); + } + sm->deleteLoginCookies(request, response); + break; + case USER_NO_GROUP: + response.redirect(ServerConfig::g_serverPath + "/userUpdateGroup"); + return; + case USER_NO_PRIVATE_KEY: + case USER_COMPLETE: + case USER_EMAIL_NOT_ACTIVATED: + auto referer = request.find("Referer"); + std::string refererString; + if (referer != request.end()) { + refererString = referer->second; + } + if(lastExternReferer != "") { + //printf("redirect to: %s\n", lastExternReferer.data()); + response.redirect(lastExternReferer); + } else if(refererString != "" && + refererString.find("login") == std::string::npos && + refererString.find("logout") == std::string::npos && + refererString.find("user_delete") == std::string::npos && + refererString != ServerConfig::g_serverPath + request.getURI()) { + std::string uri = request.getURI(); + printf("request uri: %s, redirect to: %s\n", uri.data(), refererString.data()); + response.redirect(refererString); + } else { + //printf("redirect to: %s\n", ServerConfig::g_php_serverPath.data()); + response.redirect(ServerConfig::g_php_serverPath + "/"); + } + return; + } + + } else if(!langUpdatedByBtn) { + addError(new Error(langCatalog->gettext("Login"), langCatalog->gettext("Username and password are needed!")), false); + } + + } else { + + // on enter login page with empty form + //auto session = sm->getSession(request); + // remove old cookies and session if exist + if(mSession) { + getErrors(mSession); + sm->releaseSession(mSession); + } + sm->deleteLoginCookies(request, response); + } + +%><%@ include file="header.cpsp" %> +<%= getErrorsHtml() %> + +
    + <%@ include file="flags.cpsp" %> +
    +
    + " value="<%= presetEmail %>"/> + " /> + +
    +
    +
    + + +
    +
    +

     

    + <%@ include file="footer.cpsp" %> \ No newline at end of file diff --git a/src/cpsp/passphrase.cpsp b/src/cpsp/passphrase.cpsp index d941bffcd..e8079fec9 100644 --- a/src/cpsp/passphrase.cpsp +++ b/src/cpsp/passphrase.cpsp @@ -7,7 +7,7 @@ <%! #include "../SingletonManager/SessionManager.h" #include "../SingletonManager/LanguageManager.h" -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" //#include "Poco/Net/HTTPServerParams.h" @@ -68,13 +68,15 @@ enum PageState auto registerKeyChoice = form.get("passphrase", "no"); std::string oldPassphrase = ""; if (registerKeyChoice == "no") { - auto oldPassphrase = KeyPair::filterPassphrase(form.get("passphrase-existing", "")); + auto oldPassphrase = Passphrase::filter(form.get("passphrase-existing", "")); if(oldPassphrase != "") { - if (User::validatePassphrase(oldPassphrase, &wordSource)) { + auto word_source = Passphrase::detectMnemonic(oldPassphrase); + if (word_source) { // passphrase is valid if(PAGE_FORCE_ASK_PASSPHRASE == state) { - auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, wordSource); + + auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, word_source); if(-2 == compareResult) { response.redirect(ServerConfig::g_serverPath + "/error500"); return; @@ -96,7 +98,8 @@ enum PageState } } else if (registerKeyChoice == "yes") { - mSession->generatePassphrase(); + auto passphrase = Passphrase::generate(wordSource); + mSession->setPassphrase(passphrase); } } } @@ -104,7 +107,7 @@ enum PageState // double check passphrase auto passphrase = mSession->getOldPassphrase(); auto langWordSource = wordSource; - if("" != passphrase && !User::validatePassphrase(passphrase, &wordSource)) { + if("" != passphrase && !Passphrase::detectMnemonic(passphrase)) { addError(new Error("PassphrasePage", "Invalid Passphrase after double check")); addError(new ParamError("PassphrasePage", "passphrase", passphrase.data())); if(!mSession->getNewUser().isNull()) { @@ -117,8 +120,8 @@ enum PageState } //printf("wordSource: %d, langWordSource: %d\n", (int)wordSource, (int)langWordSource); if(wordSource != langWordSource) { - mSession->generatePassphrase(); - User::validatePassphrase(passphrase, &wordSource); + //mSession->generatePassphrase(); + mSession->setPassphrase(Passphrase::generate(wordSource)); } if(mSession->getSessionState() == SESSION_STATE_PASSPHRASE_GENERATED && state != PAGE_ASK_ENSURE_PASSPHRASE) { @@ -160,7 +163,7 @@ enum PageState
    <%= gettext("Deine Passphrase (Groß/Kleinschreibung beachten)") %>:
    -

    <%= mSession->getPassphrase() %>

    +

    <%= mSession->getPassphrase()->getString() %>

    <%= gettext("Was zu tun ist:") %>
    @@ -212,7 +215,7 @@ enum PageState
    diff --git a/src/cpsp/registerAdmin.cpsp b/src/cpsp/registerAdmin.cpsp index 4f74803c1..ca8752299 100644 --- a/src/cpsp/registerAdmin.cpsp +++ b/src/cpsp/registerAdmin.cpsp @@ -6,23 +6,42 @@ <%@ header include="SessionHTTPRequestHandler.h" %> <%! #include "../SingletonManager/SessionManager.h" +#include "../controller/Group.h" +#include "../lib/DataTypeConverter.h" + #include "Poco/Net/HTTPCookie.h" #include "../ServerConfig.h" + %> <%% const char* pageName = "Admin Registrieren"; - //auto sm = SessionManager::getInstance(); + auto sm = SessionManager::getInstance(); bool userReturned = false; if(!form.empty()) { - userReturned = mSession->adminCreateUser( - form.get("register-first-name", ""), - form.get("register-last-name", ""), - form.get("register-email", "") - ); - getErrors(mSession); + auto group_id_string = form.get("register-group", "0"); + int group_id = 0; + if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } + if(!errorCount()) { + userReturned = mSession->adminCreateUser( + form.get("register-first-name", ""), + form.get("register-last-name", ""), + form.get("register-email", ""), + group_id + ); + getErrors(mSession); + } + } + + auto groups = controller::Group::listAll(); %><%@ include file="header_old.cpsp" %> @@ -54,6 +73,12 @@ "/>

    + diff --git a/src/cpsp/registerDirect.cpsp b/src/cpsp/registerDirect.cpsp index 6eadb19dc..f6c3dc49a 100644 --- a/src/cpsp/registerDirect.cpsp +++ b/src/cpsp/registerDirect.cpsp @@ -5,7 +5,10 @@ <%@ header include="PageRequestMessagedHandler.h" %> <%! #include "../SingletonManager/SessionManager.h" +#include "../controller/Group.h" +#include "../lib/DataTypeConverter.h" #include "Poco/Net/HTTPCookie.h" + %> <%% const char* pageName = "Registrieren"; @@ -24,12 +27,22 @@ session->setClientIp(user_host); response.addCookie(session->getLoginCookie()); } + auto group_id_string = form.get("register-group", "0"); + int group_id = 0; + if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) { + addError(new Error("Group id", "group_id not integer")); + } else { + if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) { + addError(new Error("Int Convert Error", "Error converting group_id to int")); + } + } userReturned = session->createUserDirect( form.get("register-first-name", ""), form.get("register-last-name", ""), form.get("register-email", ""), - form.get("register-password", "") + form.get("register-password", ""), + group_id ); getErrors(session); @@ -48,6 +61,9 @@ // remove old cookies if exist sm->deleteLoginCookies(request, response); } + + auto groups = controller::Group::listAll(); + %><%@ include file="header.cpsp" %> <%= getErrorsHtml() %>
    @@ -67,6 +83,13 @@ +
    diff --git a/src/cpsp/saveKeys.cpsp b/src/cpsp/saveKeys.cpsp index 03fe1b763..d157ceaed 100644 --- a/src/cpsp/saveKeys.cpsp +++ b/src/cpsp/saveKeys.cpsp @@ -19,7 +19,8 @@ enum PageState const char* pageName = "Daten auf Server speichern?"; bool hasErrors = mSession->errorCount() > 0; // crypto key only in memory, if user has tipped in his passwort in this session - bool hasPassword = mSession->getUser()->hasCryptoKey(); + auto user = mSession->getNewUser(); + bool hasPassword = user->getModel()->hasPrivateKeyEncrypted(); PageState state = PAGE_ASK; auto uri_start = ServerConfig::g_php_serverPath;//request.serverParams().getServerName(); @@ -123,7 +124,7 @@ enum PageState Zurück zur Startseite
    diff --git a/src/cpsp/translatePassphrase.cpsp b/src/cpsp/translatePassphrase.cpsp index afc38e958..cd24f3f48 100644 --- a/src/cpsp/translatePassphrase.cpsp +++ b/src/cpsp/translatePassphrase.cpsp @@ -5,7 +5,7 @@ <%@ page form="true" %> <%@ page compressed="true" %> <%! -#include "../Crypto/KeyPair.h" +#include "../Crypto/KeyPairEd25519.h" #include "../ServerConfig.h" %> <%% @@ -29,16 +29,17 @@ { inputPassphrase = form.get("inputPassphrase", ""); - auto localPassphrase = KeyPair::filterPassphrase(inputPassphrase); + auto localPassphrase = Passphrase::filter(inputPassphrase); auto btnGenerate = form.get("btnGenerate", ""); if("" != btnGenerate) { - mSession->generatePassphrase(); - localPassphrase = mSession->getOldPassphrase(); + auto passphrase_gen = Passphrase::generate(wordSource); + + localPassphrase = passphrase_gen->getString(); inputPassphrase = localPassphrase; } - - if(localPassphrase != "" && !User::validatePassphrase(localPassphrase, &wordSource)) { + auto passphrase_object = Passphrase::create(localPassphrase, wordSource); + if(localPassphrase != "" && passphrase_object.isNull() || !passphrase_object->checkIfValid()) { addError(new Error( gettext("Fehler"), gettext("Diese Passphrase ist ungültig, bitte überprüfen oder neu generieren (lassen).") @@ -49,7 +50,8 @@ } else { targetSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]; } - passphrase = KeyPair::passphraseTransform(localPassphrase, wordSource, targetSource); + auto transformed_passphrase_obj = passphrase_object->transform(targetSource); + passphrase = transformed_passphrase_obj->getString(); } diff --git a/src/cpsp/updateUser.cpsp b/src/cpsp/updateUser.cpsp deleted file mode 100644 index 43e3a311a..000000000 --- a/src/cpsp/updateUser.cpsp +++ /dev/null @@ -1,69 +0,0 @@ -<%@ page class="UpdateUserPage" %> -<%@ page form="true" %> -<%@ page baseClass="SessionHTTPRequestHandler" %> -<%@ page ctorArg="Session*" %> -<%@ header include="SessionHTTPRequestHandler.h" %> -<%@ page compressed="true" %> -<%! -#include "../SingletonManager/SessionManager.h" -#include "Poco/Net/HTTPCookie.h" -#include "../model/Profiler.h" -%> -<%% - const char* pageName = "Update"; - Profiler timeUsed; - auto user = mSession->getUser(); - - if(!form.empty()) { - auto pwd = form.get("update-password", ""); - if(pwd != "") { - if(pwd != form.get("update-password", "")) { - session->addError(new Error("Passwort", "Passwörter sind nicht identisch.")); - } else { - userReturned = session->getUser()->setNewPassword( - form.get("update-password") - ); - } - } - } -%><%@ include file="header.cpsp" %> -
    -

    Einen neuen Account anlegen

    - <% if(!form.empty()) {%> -
    -
    - .. -
    -
    - <% } else { %> -
    - - <% if(!form.empty() && !userReturned) {%> - <%= session->getErrorsHtml() %> - <%} %> -
    - Account anlegen -

    Bitte gebe deine Daten um einen Account anzulegen

    -

    - - "/> -

    -

    - - "/> -

    -

    - - -

    -

    - - -

    -
    - - -
    - <% } %> -
    -<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/userUpdateGroup.cpsp b/src/cpsp/userUpdateGroup.cpsp new file mode 100644 index 000000000..1fb1c4105 --- /dev/null +++ b/src/cpsp/userUpdateGroup.cpsp @@ -0,0 +1,62 @@ +<%@ page class="UserUpdateGroupPage" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%@ page compressed="true" %> +<%! + +#include "../controller/Group.h" +#include "../SingletonManager/SessionManager.h" + +enum PageState { + PAGE_STATE_OVERVIEW, + PAGE_STATE_REQUEST_IS_RUNNING +}; + +%> +<%% + const char* pageName = gettext("Gruppe wählen"); + auto user = mSession->getNewUser(); + auto sm = SessionManager::getInstance(); + PageState state = PAGE_STATE_OVERVIEW; + + if(!form.empty()) { + } + + auto groups = controller::Group::listAll(); + + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
    + <% if(PAGE_STATE_OVERVIEW == state ) { %> +
    +

    <%= gettext("Gruppe wählen") %>

    +
    +

    <%= gettext("Bitte wähle die Gruppe/Gemeinschaft aus, zu der du gehörst.") %>

    +

    <%= gettext("Du bekommst eine Bestätigungsmail, nachdem dein Beitritt bestätigt wurde.") %>

    +
    +
    +
    +
    <%= gettext("Auswahl") %>
    +
    Name
    +
    Alias
    +
    Url
    +
    <%= gettext("Description") %>
    +
    + <% for(auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); %> +
    +
    +
    <%= group_model->getName() %>
    +
    <%= group_model->getAlias() %>
    +
    <%= group_model->getUrl() %>
    +
    <%= group_model->getDescription()%>
    +
    + <% } %> + "/> +
    +
    + <% } %> +
    +<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/updateUserPassword.cpsp b/src/cpsp/userUpdatePassword.cpsp similarity index 98% rename from src/cpsp/updateUserPassword.cpsp rename to src/cpsp/userUpdatePassword.cpsp index 364b21c7f..0bb915a52 100644 --- a/src/cpsp/updateUserPassword.cpsp +++ b/src/cpsp/userUpdatePassword.cpsp @@ -1,4 +1,4 @@ -<%@ page class="UpdateUserPasswordPage" %> +<%@ page class="UserUpdatePasswordPage" %> <%@ page baseClass="SessionHTTPRequestHandler" %> <%@ page ctorArg="Session*" %> <%@ header include="SessionHTTPRequestHandler.h" %> From be6ee6261ec6e721f2410368e32b6d4e90a9be70 Mon Sep 17 00:00:00 2001 From: Dario via Pythagoras Date: Tue, 6 Oct 2020 12:03:25 +0200 Subject: [PATCH 090/195] add linux parse file --- unix_parse_proto.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 unix_parse_proto.sh diff --git a/unix_parse_proto.sh b/unix_parse_proto.sh new file mode 100755 index 000000000..3727cc985 --- /dev/null +++ b/unix_parse_proto.sh @@ -0,0 +1,19 @@ +#!/bin/bash +if [ ! -d "./src/cpp/proto" ] ; then + mkdir ./src/cpp/proto +fi +if [ ! -d "./src/cpp/proto/gradido" ] ; then + mkdir ./src/cpp/proto/gradido +fi +PROTOC_PATH=./dependencies/grpc/build/third_party/protobuf +CPP_PLUGIN_PATH=./dependencies/grpc/build +$PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto + +if [ ! -d "./src/cpp/proto/hedera" ] ; then + mkdir ./src/cpp/proto/hedera +fi + +GOOGLE_PROTOBUF_INCLUDES=./dependencies/grpc/third_party/protobuf/src +$PROTOC_PATH/protoc --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto + + From 582a9c2f4fec67a77a523e6ac07d8ae5e029168b Mon Sep 17 00:00:00 2001 From: dario Linux Date: Tue, 6 Oct 2020 15:44:11 +0200 Subject: [PATCH 091/195] update cmake for unix --- CMakeLists.txt | 246 ++++++++++++++++----------------- compile_pot.sh | 0 src/cpp/Crypto/KeyPairHedera.h | 1 - src/cpp/main.cpp | 1 - src/proto | 2 +- 5 files changed, 123 insertions(+), 127 deletions(-) mode change 100644 => 100755 compile_pot.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cc51b235..4932e21e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.18.2) project(Gradido_LoginServer C CXX) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin" ) @@ -16,11 +16,10 @@ include_directories( "dependencies/grpc/third_party/protobuf/src" #"dependencies/grpc/third_party/boringssl-with-bazel/src/include" "src/cpp/proto" - #"dependencies/mariadb-connector-c/build/include" - #"dependencies/mariadb-connector-c/include" - #"import/mariadb/include" ) +set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") + FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") @@ -59,51 +58,84 @@ SET(LOCAL_TEST_SRC aux_source_directory("src/cpp" LOCAL_SRCS) if(MSVC) -# src -source_group("controller" FILES ${CONTROLLER}) -source_group("proto\\gradido" FILES ${PROTO_GRADIDO}) -source_group("proto\\hedera" FILES ${PROTO_HEDERA}) -source_group("tinf" FILES ${TINF}) -source_group("Crypto" FILES ${CRYPTO}) -source_group("tasks" FILES ${TASKS}) -source_group("model\\table" FILES ${MODEL_TABLE}) -source_group("model\\email" FILES ${MODEL_EMAIL}) -source_group("model\\hedera" FILES ${MODEL_HEDERA}) -source_group("model" FILES ${MODEL}) -source_group("mysql" FILES ${MYSQL}) -source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) -source_group("lib" FILES ${LIB_SRC}) -source_group("HTTP-Interface" FILES ${HTTPInterface}) -source_group("Json-Interface" FILES ${JSONInterface}) -source_group("Test\\crypto" FILES ${TEST_CRYPTO}) -source_group("Test\\model\\table" FILES ${TEST_MODEL_TABLE}) -source_group("Test\\model" FILES ${TEST_MODEL}) -source_group("Test\\controller" FILES ${TEST_CONTROLLER}) -source_group("Test" FILES ${TEST}) + # src + source_group("controller" FILES ${CONTROLLER}) + source_group("proto\\gradido" FILES ${PROTO_GRADIDO}) + source_group("proto\\hedera" FILES ${PROTO_HEDERA}) + source_group("tinf" FILES ${TINF}) + source_group("Crypto" FILES ${CRYPTO}) + source_group("tasks" FILES ${TASKS}) + source_group("model\\table" FILES ${MODEL_TABLE}) + source_group("model\\email" FILES ${MODEL_EMAIL}) + source_group("model\\hedera" FILES ${MODEL_HEDERA}) + source_group("model" FILES ${MODEL}) + source_group("mysql" FILES ${MYSQL}) + source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) + source_group("lib" FILES ${LIB_SRC}) + source_group("HTTP-Interface" FILES ${HTTPInterface}) + source_group("Json-Interface" FILES ${JSONInterface}) + source_group("Test\\crypto" FILES ${TEST_CRYPTO}) + source_group("Test\\model\\table" FILES ${TEST_MODEL_TABLE}) + source_group("Test\\model" FILES ${TEST_MODEL}) + source_group("Test\\controller" FILES ${TEST_CONTROLLER}) + source_group("Test" FILES ${TEST}) endif(MSVC) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() -#add_subdirectory("dependencies/curl") -#add_subdirectory("dependencies/mariadb-connector-c") - add_executable(Gradido_LoginServer ${LOCAL_SRCS}) -#SUBDIRS("src/test") + + +set(DEP_PATH "dependencies") +set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") +set(GRPC_PATH "${DEP_PATH}/grpc/build") +set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types") +set(GRPC_CARES_PATH "${GRPC_PATH}/third_party/cares/cares/lib") +set(GRPC_BORING_SSL_PATH "${GRPC_PATH}/third_party/boringssl-with-bazel") +set(GRPC_RE2_PATH "${GRPC_PATH}/third_party/re2") +set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf") if(WIN32) -find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "dependencies/mariadb-connector-c/build/libmariadb/Release" REQUIRED) -#find_library(MYSQL_LIBRARIES_DEBUG mariadbclient.lib PATHS "import/mariadb/lib/debug") -find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "dependencies/mariadb-connector-c/build/libmariadb/Debug" REQUIRED) -set(GRPC_PATH "dependencies/grpc/_build/Debug") -set(GRPC_ABSL_PATH "dependencies/grpc/_build/third_party/abseil-cpp/absl/types/Debug") -set(GRPC_CARES_PATH "dependencies/grpc/_build/third_party/cares/cares/lib/Debug") -set(GRPC_BORING_SSL_PATH "dependencies/grpc/_build/third_party/boringssl-with-bazel/Debug") -set(GRPC_RE2_PATH "dependencies/grpc/_build/third_party/re2/Debug") -set(GRPC_PROTOBUF_DEBUG_PATH "dependencies/grpc/_build/third_party/protobuf/Debug") + find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) + find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "${MARIADB_CONNECTOR_PATH}/Debug" REQUIRED) + + set(GRPC_PATH "${GRPC_PATH}/Debug") + set(GRPC_ABSL_PATH "${GRPC_ABSL_PATH}/Debug") + set(GRPC_CARES_PATH "${GRPC_CARES_PATH}/Debug") + set(GRPC_BORING_SSL_PATH "${GRPC_CGRPC_BORING_SSL_PATHARES_PATH}/Debug") + set(GRPC_RE2_PATH "${GRPC_RE2_PATH}/Debug") + set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}/Debug") + + find_library(PROTOBUF_LIB_DEBUG libprotobufd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) + find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) + find_library(PROTOBUF_LIBC_DEBUG libprotocd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) + + set(PROTOBUF_DEBUG_LIBS + ${PROTOBUF_LIB_DEBUG} + ${PROTOBUF_LIB_LITE_DEBUG} + ${PROTOBUF_LIBC_DEBUG} + ) + + list(REMOVE_ITEM CONAN_LIBS "libeay32.lib") + list(REMOVE_ITEM CONAN_LIBS "ssleay32.lib") + + +else (WIN32) +# message(STATUS ${MARIADB_CONNECTOR_PATH}) + find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) + set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") + + list(REMOVE_ITEM CONAN_LIBS "ssl") + list(REMOVE_ITEM CONAN_LIBS "crypto") + + +endif(WIN32) + +# grpc libs find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) @@ -113,15 +145,18 @@ find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) +# grpc third party libs find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_RE2 re2 ${GRPC_RE2_PATH} REQUIRED) -find_library(PROTOBUF_LIB_DEBUG libprotobufd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) -find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) -find_library(PROTOBUF_LIBC_DEBUG libprotocd ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +find_library(GRPC_RE2 re2 PATHS ${GRPC_RE2_PATH} REQUIRED) + +find_library(PROTOBUF_LIB libprotobuf.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) +find_library(PROTOBUF_LIB_LITE libprotobuf-lite.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) +find_library(PROTOBUF_LIBC libprotoc.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) + +find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access PATHS ${GRPC_ABSL_PATH} REQUIRED) -find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access ${GRPC_ABSL_PATH} REQUIRED) set(GRPC_LIBS ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} @@ -131,74 +166,49 @@ set(GRPC_LIBS ${GRPC_BORING_SSL_SSL} ${GRPC_RE2} ) -set(PROTOBUF_DEBUG_LIBS - ${PROTOBUF_LIB_DEBUG} - ${PROTOBUF_LIB_LITE_DEBUG} - ${PROTOBUF_LIBC_DEBUG} + +set(PROTOBUF_LIBS + ${PROTOBUF_LIB} + ${PROTOBUF_LIB_LITE} + ${PROTOBUF_LIBC} ) -set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") +if(WIN32) -#set(POCO_DEBUG_PATH "I:/FremdCode/C++/poco/win64/lib/Debug") -#find_library(POCO_DEBUG_FOUNDATION PocoFoundationd PocoFoundation PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_DATA PocoDatad PocoData PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_NET PocoNetd PocoNet PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_NET_SSL PocoNetSSLd PocoNetSSL PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_UTIL PocoUtild PocoUtil PATHS ${POCO_DEBUG_PATH} REQUIRED) -#find_library(POCO_DEBUG_CRYPTO PocoCryptod PocoCrypto PATHS ${POCO_DEBUG_PATH} REQUIRED) - -#set(POCO_DEBUG_LIBS ${POCO_DEBUG_FOUNDATION} ${POCO_DEBUG_UTIL} ${POCO_DEBUG_DATA} ${POCO_DEBUG_NET} ${POCO_DEBUG_NET_SSL} ${POCO_DEBUG_CRYPTO}) -#include_directories( -# "I:/FremdCode/C++/poco/Foundation/include" -# "I:/FremdCode/C++/poco/Data/include" -# "I:/FremdCode/C++/poco/Net/include" - #"I:/FremdCode/C++/poco/NetSSL_Win/include" -# "I:/FremdCode/C++/poco/NetSSL_OpenSSL/include" -# "I:/FremdCode/C++/poco/Crypto/include" -# "I:/FremdCode/C++/poco/Util/include" -# "I:/FremdCode/C++/ssl/include" -#) - -set(CMAKE_CXX_FLAGS "/MP /EHsc") -#set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") -#set(CMAKE_CXX_FLAGS_RELEASE "-O3") + set(CMAKE_CXX_FLAGS "/MP /EHsc") + #set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") + #set(CMAKE_CXX_FLAGS_RELEASE "-O3") else(WIN32) -set(GRPC_BORING_SSL_PATH "dependencies/grpc/build/third_party/boringssl-with-bazel") -find_library(GRPC_BORING_SSL_CRYPTO crypto ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_SSL ssl ${GRPC_BORING_SSL_PATH} REQUIRED) -set(GRPC_LIBS - #${GRPC_BORING_SSL_CRYPTO} - #${GRPC_BORING_SSL_SSL} -) -#find_package(OpenSSL REQUIRED) -find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) -set(gRPC_SSL_PROVIDER "module") -find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) -find_package(Threads REQUIRED) -set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) -#find_package(Poco REQUIRED) -#find_package(libsodium REQUIRED) -#find_package(gtest REQUIRED) -find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) -# set vars for mariadb cmake files -set(INSTALL_BINDIR "bin") -set(INSTALL_PLUGINDIR "bin") -OPTION(WITH_SSL "" OFF) -add_subdirectory("dependencies/mariadb-connector-c") + #find_package(OpenSSL REQUIRED) + #find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) + #set(gRPC_SSL_PROVIDER "module") + #find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) + find_package(Threads REQUIRED) + set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) + + #find_package(Poco REQUIRED) + #find_package(libsodium REQUIRED) + #find_package(gtest REQUIRED) + #find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) + # set vars for mariadb cmake files + set(INSTALL_BINDIR "bin") + set(INSTALL_PLUGINDIR "bin") +# OPTION(WITH_SSL "" OFF) +# add_subdirectory("dependencies/mariadb-connector-c") -include_directories( - "dependencies/mariadb-connector-c/include" - "build/dependencies/mariadb-connector-c/include" - #${OpenSSL_INCLUDE_DIR} - #${Poco_INCLUDE_DIR} - #${libsodium_INCLUDE_DIR} - #${gtest_INCLUDE_DIR} -) + include_directories( + # "dependencies/mariadb-connector-c/include" +# "build/dependencies/mariadb-connector-c/include" + #${OpenSSL_INCLUDE_DIR} + #${Poco_INCLUDE_DIR} + #${libsodium_INCLUDE_DIR} + #${gtest_INCLUDE_DIR} + ) @@ -206,28 +216,16 @@ endif(WIN32) add_subdirectory("dependencies/grpc/third_party/abseil-cpp") -#target_link_libraries(Gradido_LoginServer absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings)# ${CONAN_LIBS} ${IROHA_ED25519}) -message(STATUS "Conan libs: ") -list(REMOVE_ITEM CONAN_LIBS "ssl") -list(REMOVE_ITEM CONAN_LIBS "crypto") -foreach(i ${CONAN_LIBS}) - -message(STATUS ${i}) - -endforeach(i) - if(WIN32) -TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) -TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) -else(WIN32) -target_link_libraries(Gradido_LoginServer gRPC::grpc++) -target_link_libraries(Gradido_LoginServer ${CONAN_LIBS}) -target_link_libraries(Gradido_LoginServer libmariadb )# ${GRPC_LIBS} protoc protobuf pthread) -#target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) - - + TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) + TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) +else(WIN32) # unix +# target_link_libraries(Gradido_LoginServer gRPC::grpc++) +# target_link_libraries(Gradido_LoginServer ) + target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${GRPC_LIBS} ${PROTOBUF_LIBS} )# ${GRPC_LIBS} protoc protobuf pthread) + #target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) endif(WIN32) @@ -252,7 +250,7 @@ enable_testing() add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") -target_link_libraries(Gradido_LoginServer_Test absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ${IROHA_ED25519}) +target_link_libraries(Gradido_LoginServer_Test absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) diff --git a/compile_pot.sh b/compile_pot.sh old mode 100644 new mode 100755 diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index 769f29af6..f342164d6 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -14,7 +14,6 @@ #include "sodium.h" #include "SecretKeyCryptography.h" -#include "iroha-ed25519/include/ed25519/ed25519.h" #include "../lib/DataTypeConverter.h" class KeyPairHedera : public IKeyPair diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 899779fef..8d3858923 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -3,7 +3,6 @@ #include "proto/gradido/TransactionBody.pb.h" -#include "model/User.h" #include "model/Session.h" #include "lib/Profiler.h" #include "ServerConfig.h" diff --git a/src/proto b/src/proto index 81a461566..72e8fe7b7 160000 --- a/src/proto +++ b/src/proto @@ -1 +1 @@ -Subproject commit 81a461566e46d71533dc3e284fa075d7d68fd020 +Subproject commit 72e8fe7b73a1aaf2d057d2fef59ade9268830008 From add8544cd501a5bd849d85520b3ece17f7d3bacb Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 6 Oct 2020 15:41:34 +0200 Subject: [PATCH 092/195] update code because irohe-ed25519 was removed --- src/cpp/Crypto/KeyPairHedera.cpp | 10 +++--- src/cpp/Crypto/KeyPairHedera.h | 4 +-- .../HTTPInterface/AdminHederaAccountPage.cpp | 2 +- .../HTTPInterface/RepairDefectPassphrase.cpp | 33 +++++++++---------- src/cpp/main.cpp | 3 +- src/cpsp/adminHederaAccount.cpsp | 2 +- src/cpsp/repairDefectPassphrase.cpsp | 3 +- 7 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/cpp/Crypto/KeyPairHedera.cpp b/src/cpp/Crypto/KeyPairHedera.cpp index e16b76e05..ac974fdc1 100644 --- a/src/cpp/Crypto/KeyPairHedera.cpp +++ b/src/cpp/Crypto/KeyPairHedera.cpp @@ -58,16 +58,16 @@ KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeyS } case 44: // DER encoded public key if (0 == sodium_memcmp(publicKey, *derPrefixPub, derPrefixPub->size())) { - memcpy(mPublicKey, &publicKey[derPrefixPub->size()], ed25519_pubkey_SIZE); + memcpy(mPublicKey, &publicKey[derPrefixPub->size()], crypto_sign_PUBLICKEYBYTES); } break; default: throw Poco::Exception("[KeyPairHedera] invalid public key"); } } - auto public_key_2 = mm->getFreeMemory(ed25519_pubkey_SIZE); + auto public_key_2 = mm->getFreeMemory(crypto_sign_PUBLICKEYBYTES); crypto_sign_ed25519_sk_to_pk(*public_key_2, *mPrivateKey); - if (sodium_memcmp(*public_key_2, mPublicKey, ed25519_pubkey_SIZE) != 0) { + if (sodium_memcmp(*public_key_2, mPublicKey, crypto_sign_PUBLICKEYBYTES) != 0) { throw "public keys not match"; } @@ -215,7 +215,7 @@ MemoryBin* KeyPairHedera::getPrivateKeyCopy() const MemoryBin* KeyPairHedera::getPublicKeyCopy() const { auto mm = MemoryManager::getInstance(); - auto public_key = mm->getFreeMemory(ed25519_pubkey_SIZE); - memcpy(*public_key, mPublicKey, ed25519_pubkey_SIZE); + auto public_key = mm->getFreeMemory(crypto_sign_PUBLICKEYBYTES); + memcpy(*public_key, mPublicKey, crypto_sign_PUBLICKEYBYTES); return public_key; } diff --git a/src/cpp/Crypto/KeyPairHedera.h b/src/cpp/Crypto/KeyPairHedera.h index f342164d6..b8dba9024 100644 --- a/src/cpp/Crypto/KeyPairHedera.h +++ b/src/cpp/Crypto/KeyPairHedera.h @@ -42,7 +42,7 @@ public: inline const unsigned char* getPublicKey() const { return mPublicKey; } MemoryBin* getPublicKeyCopy() const; inline std::string getPublicKeyHex() const { return DataTypeConverter::binToHex(mPublicKey, getPublicKeySize()); } - const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;} + const static size_t getPublicKeySize() {return crypto_sign_PUBLICKEYBYTES;} inline bool isTheSame(const KeyPairHedera& b) const { return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, getPublicKeySize()); @@ -89,7 +89,7 @@ private: // 32 Byte //! \brief ed25519 libsodium public key - unsigned char mPublicKey[ed25519_pubkey_SIZE]; + unsigned char mPublicKey[crypto_sign_PUBLICKEYBYTES]; }; #endif //__GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H \ No newline at end of file diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index 4bcf9b614..28c99c26a 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -202,7 +202,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), crypto_sign_PUBLICKEYBYTES); if(crypto_key.isNull()) { crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); diff --git a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp index 77fd06514..e089a38e2 100644 --- a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp +++ b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp @@ -9,7 +9,6 @@ #include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/EmailManager.h" -#include "../Crypto/KeyPair.h" #include "../Crypto/Passphrase.h" #include "../Crypto/KeyPairEd25519.h" #include "../lib/DataTypeConverter.h" @@ -53,7 +52,7 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 36 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 35 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" auto mm = MemoryManager::getInstance(); auto em = EmailManager::getInstance(); @@ -270,26 +269,26 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "
    \n"; // end include header_old.cpsp responseStream << "\n"; -#line 185 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" if("" != errorString) { responseStream << "\n"; responseStream << "\t"; -#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 185 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( errorString ); responseStream << "\n"; -#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t"; -#line 189 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 188 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\t

    Konto reparieren

    \n"; responseStream << "\t

    Der Login-Server hat festgestellt das die gespeicherte Passphrase nicht zu deinem Konto passt.

    \n"; responseStream << "\t"; -#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 191 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" if(GENERATE_PASSPHRASE == state) { responseStream << "\n"; responseStream << "\t\t"; -#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" if(new_user->canDecryptPrivateKey()) { responseStream << "\n"; responseStream << "\t\t\t

    Dein Privat Key konnte noch entschlüsselt werden. Es könnte also eine neue Passphrase generiert werden und dein aktueller Kontostand\n"; responseStream << "\t\t\tauf die neue Adresse transferiert werden.

    \n"; @@ -297,27 +296,27 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t"; -#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t

    Dein Privat Key konnte nicht entschlüsselt werden. Bitte wende dich an den Admin: "; -#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( adminEmail ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } responseStream << "\n"; responseStream << "\t"; -#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } else if(SHOW_PASSPHRASE == state) { responseStream << "\n"; responseStream << "\t\t

    Deine neue Passphrase, bitte schreibe sie dir auf (am besten auf einen Zettel) und hebe sie gut auf. \n"; responseStream << "\t\tDu brauchst sie wenn du dein Passwort vergessen hast oder dein Konto umziehen möchtest:

    \n"; responseStream << "\t\t
    Deine neue Passphrase:\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t"; -#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" responseStream << ( mSession->getPassphrase()->getString() ); responseStream << "\n"; responseStream << "\t\t\t
    \n"; @@ -328,15 +327,15 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t

    \n"; responseStream << "\t\t\n"; responseStream << "\t"; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } else if(FINISH == state) { responseStream << "\n"; responseStream << "\t\t

    Neue Daten erfolgreich gespeichert, bitte logge dich nun aus. Danach kannst du dich gerne wieder einloggen und müsstest dein Guthaben wieder auf deinem Konto haben.

    \n"; responseStream << "\t\tAusloggen\n"; responseStream << "\t"; -#line 218 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\repairDefectPassphrase.cpsp" } responseStream << "\n"; responseStream << "
    \n"; // begin include footer.cpsp diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 8d3858923..24b6f15cf 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -3,6 +3,7 @@ #include "proto/gradido/TransactionBody.pb.h" + #include "model/Session.h" #include "lib/Profiler.h" #include "ServerConfig.h" @@ -35,7 +36,7 @@ int main(int argc, char** argv) ServerConfig::g_versionString = Poco::DateTimeFormatter::format(buildDateTime, "0.%y.%m.%d"); //ServerConfig::g_versionString = "0.20.KW13.02"; printf("Version: %s\n", ServerConfig::g_versionString.data()); - printf("User size: %d Bytes, Session size: %d Bytes\n", (int)sizeof(User), (int)sizeof(Session)); + printf("User size: %d Bytes, Session size: %d Bytes\n", (int)sizeof(controller::User), (int)sizeof(Session)); printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", (int)sizeof(model::table::User), (int)sizeof(model::table::EmailOptIn)); // load word lists diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index c7ec76f98..45f2c65ae 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -181,7 +181,7 @@ KeyPairHedera key_pair(private_key, public_key); - auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE); + auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), crypto_sign_PUBLICKEYBYTES); if(crypto_key.isNull()) { crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true"); diff --git a/src/cpsp/repairDefectPassphrase.cpsp b/src/cpsp/repairDefectPassphrase.cpsp index 0e8c82e64..960466cd5 100644 --- a/src/cpsp/repairDefectPassphrase.cpsp +++ b/src/cpsp/repairDefectPassphrase.cpsp @@ -7,11 +7,10 @@ <%! #include "../SingletonManager/MemoryManager.h" #include "../SingletonManager/EmailManager.h" -#include "../Crypto/KeyPair.h" #include "../Crypto/Passphrase.h" #include "../Crypto/KeyPairEd25519.h" #include "../lib/DataTypeConverter.h" -#include "../controller/UserBackups.h" +#include "../controller/UserBackup.h" #include "../tasks/SigningTransaction.h" #include "../ServerConfig.h" From 93f371e94c2aeab167ac38c148af5eb8fd68655c Mon Sep 17 00:00:00 2001 From: dario Linux Date: Wed, 7 Oct 2020 12:39:55 +0200 Subject: [PATCH 093/195] more experiments with cmake --- CMakeLists.txt | 51 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4932e21e5..6ed33e04d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,7 @@ else (WIN32) list(REMOVE_ITEM CONAN_LIBS "ssl") list(REMOVE_ITEM CONAN_LIBS "crypto") - + list(REMOVE_ITEM CONAN_LIBS "dl") endif(WIN32) @@ -140,6 +140,7 @@ find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_LIB grpc PATHS ${GRPC_PATH} REQUIRED) +find_library(GRPC_LIB_UNSECURE grpc_unsecure PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ERROR_DETAILS grpc++_error_details PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) @@ -147,8 +148,8 @@ find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) # grpc third party libs find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +#find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) +#find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) find_library(GRPC_RE2 re2 PATHS ${GRPC_RE2_PATH} REQUIRED) find_library(PROTOBUF_LIB libprotobuf.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) @@ -157,13 +158,35 @@ find_library(PROTOBUF_LIBC libprotoc.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access PATHS ${GRPC_ABSL_PATH} REQUIRED) +# load same ssl version like used from poco +find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) +find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) +#find_library(CONAN_OPENSSL_DL dl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) +#find_library(CONAN_OPENSSL_PTHREAD pthread PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) + +set(CONAN_OPENSSL_CUSTOM_LIBS + ${CONAN_OPENSSL_SSL} + ${CONAN_OPENSSL_CRYPTO} + #${CONAN_OPENSSL_DL} +# ${CONAN_OPENSSL_PTHREAD} + ) +#foreach(i ${CONAN_LIBS_OPENSSL}) +# find_library(_LIB_${i} ${i} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) + #set(CONAN_POCO_OPENSSL_LIBS ${CONAN_POCO_OPENSSL_LIBS} ${_LIB_${i}}) +#endforeach(i) + +#${CONAN_LIB_DIRS_OPENSSL} +#${CONAN_LIBS_OPENSSL} +#find_library(CONAN_POCO_OPENSSL_LIBS NAMES ${CONAN_LIBS_OPENSSL} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) + set(GRPC_LIBS - ${GRPC_PLUSPLUS} ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} + ${GRPC_PLUSPLUS} + ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} ${GRPC_CARES} - ${GRPC_BORING_SSL_CRYPTO} - ${GRPC_BORING_SSL_SSL} +# ${GRPC_BORING_SSL_CRYPTO} +# ${GRPC_BORING_SSL_SSL} ${GRPC_RE2} ) @@ -224,10 +247,24 @@ if(WIN32) else(WIN32) # unix # target_link_libraries(Gradido_LoginServer gRPC::grpc++) # target_link_libraries(Gradido_LoginServer ) - target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${GRPC_LIBS} ${PROTOBUF_LIBS} )# ${GRPC_LIBS} protoc protobuf pthread) + target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS})# ${GRPC_LIBS} protoc protobuf pthread) #target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) endif(WIN32) +message(STATUS "link libraries:" ) +get_target_property(OUT Gradido_LoginServer LINK_LIBRARIES) +foreach(i ${OUT}) +message(STATUS ${i}) +endforeach(i) +message(STATUS "grpc libs: ") +foreach(i ${GRPC_LIBS}) +message(STATUS ${i}) +endforeach(i) +message(STATUS "boring ssl:") +message(STATUS ${GRPC_BORING_SSL_SSL}) +message(STATUS ${GRPC_BORING_SSL_CRYPTO}) +message(STATUS "Conan OpenSSL") +message(STATUS ${CONAN_POCO_OPENSSL_LIBS}) # install if(UNIX) From 5c53cf3fd15d568894852d2796538145a6b8ba54 Mon Sep 17 00:00:00 2001 From: dario Linux Date: Thu, 8 Oct 2020 08:23:09 +0200 Subject: [PATCH 094/195] build working under linux :) --- CMakeLists.txt | 116 ++++----------------- FindOpenSSL.cmake | 109 +++++++++++++++++++ conanfile.txt | 1 - src/cpp/test/crypto/TestKeyPairEd25519.cpp | 10 +- src/cpp/test/crypto/TestPassphrase.cpp | 9 +- 5 files changed, 136 insertions(+), 109 deletions(-) create mode 100644 FindOpenSSL.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ed33e04d..4275714dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,14 +14,12 @@ include_directories( "dependencies/spirit-po/include" "dependencies/grpc/include" "dependencies/grpc/third_party/protobuf/src" - #"dependencies/grpc/third_party/boringssl-with-bazel/src/include" "src/cpp/proto" ) set(MYSQL_INCLUDE_DIR "dependencies/mariadb-connector-c/include") - FILE(GLOB CONTROLLER "src/cpp/controller/*.cpp" "src/cpp/controller/*.h") FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h") FILE(GLOB HTTPInterface "src/cpp/HTTPInterface/*.h" "src/cpp/HTTPInterface/*.cpp") @@ -91,6 +89,7 @@ add_executable(Gradido_LoginServer ${LOCAL_SRCS}) set(DEP_PATH "dependencies") set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") + set(GRPC_PATH "${DEP_PATH}/grpc/build") set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types") set(GRPC_CARES_PATH "${GRPC_PATH}/third_party/cares/cares/lib") @@ -98,6 +97,8 @@ set(GRPC_BORING_SSL_PATH "${GRPC_PATH}/third_party/boringssl-with-bazel") set(GRPC_RE2_PATH "${GRPC_PATH}/third_party/re2") set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf") + + if(WIN32) find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) @@ -125,7 +126,7 @@ if(WIN32) else (WIN32) -# message(STATUS ${MARIADB_CONNECTOR_PATH}) + find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") @@ -135,109 +136,46 @@ else (WIN32) endif(WIN32) -# grpc libs -find_library(GRPC_PLUSPLUS grpc++ PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_UNSECURE grpc++_unsecure PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_REFLECTION grpc++_reflection PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_LIB grpc PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_LIB_UNSECURE grpc_unsecure PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_ERROR_DETAILS grpc++_error_details PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_RLIB gpr PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_UPB upb PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_ALTS grpc++_alts PATHS ${GRPC_PATH} REQUIRED) -find_library(GRPC_ADDRESS_SORTING address_sorting PATHS ${GRPC_PATH} REQUIRED) -# grpc third party libs -find_library(GRPC_CARES cares PATHS ${GRPC_CARES_PATH} REQUIRED) -#find_library(GRPC_BORING_SSL_CRYPTO crypto PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) -#find_library(GRPC_BORING_SSL_SSL ssl PATHS ${GRPC_BORING_SSL_PATH} REQUIRED) -find_library(GRPC_RE2 re2 PATHS ${GRPC_RE2_PATH} REQUIRED) - -find_library(PROTOBUF_LIB libprotobuf.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) -find_library(PROTOBUF_LIB_LITE libprotobuf-lite.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) -find_library(PROTOBUF_LIBC libprotoc.a PATHS ${GRPC_PROTOBUF_PATH} REQUIRED) - -find_library(GRPC_ABSL_BAD_OPTIONAL_ACCESS absl_bad_optional_access PATHS ${GRPC_ABSL_PATH} REQUIRED) # load same ssl version like used from poco +find_package(OpenSSL PATHS . NO_DEFAULT_PATH) + find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) -#find_library(CONAN_OPENSSL_DL dl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) -#find_library(CONAN_OPENSSL_PTHREAD pthread PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(CONAN_OPENSSL_CUSTOM_LIBS ${CONAN_OPENSSL_SSL} ${CONAN_OPENSSL_CRYPTO} - #${CONAN_OPENSSL_DL} -# ${CONAN_OPENSSL_PTHREAD} - ) -#foreach(i ${CONAN_LIBS_OPENSSL}) -# find_library(_LIB_${i} ${i} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) - #set(CONAN_POCO_OPENSSL_LIBS ${CONAN_POCO_OPENSSL_LIBS} ${_LIB_${i}}) -#endforeach(i) - -#${CONAN_LIB_DIRS_OPENSSL} -#${CONAN_LIBS_OPENSSL} -#find_library(CONAN_POCO_OPENSSL_LIBS NAMES ${CONAN_LIBS_OPENSSL} PATHS ${CONAN_LIB_DIRS_OPENSSL} NO_DEFAULT_PATH) - -set(GRPC_LIBS - ${GRPC_PLUSPLUS} - ${GRPC_REFLECTION} ${GRPC_UNSECURE} ${GRPC_LIB} - ${GRPC_ERROR_DETAILS} ${GRPC_RLIB} ${GRPC_UPB} ${GRPC_ALTS} - ${GRPC_ABSL_BAD_OPTIONAL_ACCESS} ${GRPC_ADDRESS_SORTING} - ${GRPC_CARES} -# ${GRPC_BORING_SSL_CRYPTO} -# ${GRPC_BORING_SSL_SSL} - ${GRPC_RE2} ) -set(PROTOBUF_LIBS - ${PROTOBUF_LIB} - ${PROTOBUF_LIB_LITE} - ${PROTOBUF_LIBC} -) +set(BUILD_TESTING OFF) +set(gRPC_SSL_PROVIDER "package") +add_subdirectory("dependencies/grpc/") +message(STATUS "Using gRPC via add_subdirectory.") if(WIN32) - set(CMAKE_CXX_FLAGS "/MP /EHsc") #set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") #set(CMAKE_CXX_FLAGS_RELEASE "-O3") else(WIN32) - #find_package(OpenSSL REQUIRED) - #find_package(PROTOBUF PATHS "dependencies/grpc/build/third_party/protobuf" REQUIRED) - #set(gRPC_SSL_PROVIDER "module") - #find_package(gRPC PATHS "dependencies/grpc/build" REQUIRED) - find_package(Threads REQUIRED) - set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) - #find_package(Poco REQUIRED) - #find_package(libsodium REQUIRED) - #find_package(gtest REQUIRED) - #find_library(IROHA_ED25519 ed25519 PATHS "dependencies/iroha-ed25519/build" REQUIRED) - # set vars for mariadb cmake files set(INSTALL_BINDIR "bin") set(INSTALL_PLUGINDIR "bin") -# OPTION(WITH_SSL "" OFF) -# add_subdirectory("dependencies/mariadb-connector-c") - include_directories( - # "dependencies/mariadb-connector-c/include" -# "build/dependencies/mariadb-connector-c/include" - #${OpenSSL_INCLUDE_DIR} - #${Poco_INCLUDE_DIR} - #${libsodium_INCLUDE_DIR} - #${gtest_INCLUDE_DIR} + ${CONAN_INCLUDE_DIRS_OPENSSL} ) - endif(WIN32) -add_subdirectory("dependencies/grpc/third_party/abseil-cpp") + +set(GRPC_LIBS libprotobuf grpc++_reflection grpc++) +target_link_libraries(Gradido_LoginServer ${CONAN_LIBS}) if(WIN32) @@ -245,26 +183,8 @@ if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) # unix -# target_link_libraries(Gradido_LoginServer gRPC::grpc++) -# target_link_libraries(Gradido_LoginServer ) - target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS})# ${GRPC_LIBS} protoc protobuf pthread) - #target_link_libraries(Gradido_LoginServer ${OpenSSL_LIBS} ${Poco_LIBS} ${libsodium_LIBS} ) - + target_link_libraries(Gradido_LoginServer ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) endif(WIN32) -message(STATUS "link libraries:" ) -get_target_property(OUT Gradido_LoginServer LINK_LIBRARIES) -foreach(i ${OUT}) -message(STATUS ${i}) -endforeach(i) -message(STATUS "grpc libs: ") -foreach(i ${GRPC_LIBS}) -message(STATUS ${i}) -endforeach(i) -message(STATUS "boring ssl:") -message(STATUS ${GRPC_BORING_SSL_SSL}) -message(STATUS ${GRPC_BORING_SSL_CRYPTO}) -message(STATUS "Conan OpenSSL") -message(STATUS ${CONAN_POCO_OPENSSL_LIBS}) # install if(UNIX) @@ -282,19 +202,19 @@ enable_testing() # ---------------------- Test ----------------------------------------- #project(Gradido_LoginServer_Test C CXX) #_TEST_BUILD - +#find_package(gtest) add_executable(Gradido_LoginServer_Test ${LOCAL_SRCS} ${LOCAL_TEST_SRC}) target_compile_definitions(Gradido_LoginServer_Test PUBLIC "_TEST_BUILD") -target_link_libraries(Gradido_LoginServer_Test absl::base absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::strings ${CONAN_LIBS} ) +target_link_libraries(Gradido_LoginServer_Test ${CONAN_LIBS} ) if(WIN32) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test optimized ${MYSQL_LIBRARIES} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi) TARGET_LINK_LIBRARIES(Gradido_LoginServer_Test debug ${GRPC_LIBS} ${PROTOBUF_DEBUG_LIBS}) else(WIN32) - target_link_libraries(Gradido_LoginServer_Test libmariadb protoc protobuf pthread) + target_link_libraries(Gradido_LoginServer_Test ${MYSQL_LIBRARIES} ${CONAN_OPENSSL_CUSTOM_LIBS} ${GRPC_LIBS} ${CMAKE_DL_LIBS} ${PROTOBUF_LIBS}) endif(WIN32) add_test(NAME main COMMAND Gradido_LoginServer_Test) \ No newline at end of file diff --git a/FindOpenSSL.cmake b/FindOpenSSL.cmake new file mode 100644 index 000000000..4a4fec7df --- /dev/null +++ b/FindOpenSSL.cmake @@ -0,0 +1,109 @@ + + +function(conan_message MESSAGE_OUTPUT) + if(NOT CONAN_CMAKE_SILENT_OUTPUT) + message(${ARGV${0}}) + endif() +endfunction() + + + + +include(FindPackageHandleStandardArgs) + +conan_message(STATUS "Conan: Using autogenerated FindOpenSSL.cmake") +# Global approach +set(OpenSSL_FOUND 1) +set(OpenSSL_VERSION "1.0.2o") + +find_package_handle_standard_args(OpenSSL REQUIRED_VARS + OpenSSL_VERSION VERSION_VAR OpenSSL_VERSION) +mark_as_advanced(OpenSSL_FOUND OpenSSL_VERSION) + + +set(OpenSSL_INCLUDE_DIRS "${CONAN_INCLUDE_DIRS_OPENSSL}") +set(OpenSSL_INCLUDE_DIR "${CONAN_INCLUDE_DIRS_OPENSSL}") +set(OpenSSL_INCLUDES "${CONAN_INCLUDE_DIRS_OPENSSL}") +set(OpenSSL_RES_DIRS "${CONAN_RES_DIRS_OPENSSL}") +set(OpenSSL_DEFINITIONS ) +set(OpenSSL_LINKER_FLAGS_LIST + "$<$,SHARED_LIBRARY>:>" + "$<$,MODULE_LIBRARY>:>" + "$<$,EXECUTABLE>:>" +) +set(OpenSSL_COMPILE_DEFINITIONS ) +set(OpenSSL_COMPILE_OPTIONS_LIST "" "") +set(OpenSSL_COMPILE_OPTIONS_C "") +set(OpenSSL_COMPILE_OPTIONS_CXX "") +set(OpenSSL_LIBRARIES_TARGETS "") # Will be filled later, if CMake 3 +set(OpenSSL_LIBRARIES "") # Will be filled later +set(OpenSSL_LIBS "") # Same as OpenSSL_LIBRARIES +set(OpenSSL_FRAMEWORKS_FOUND "") # Will be filled later +set(OpenSSL_BUILD_MODULES_PATHS ) + + +mark_as_advanced(OpenSSL_INCLUDE_DIRS + OpenSSL_INCLUDE_DIR + OpenSSL_INCLUDES + OpenSSL_DEFINITIONS + OpenSSL_LINKER_FLAGS_LIST + OpenSSL_COMPILE_DEFINITIONS + OpenSSL_COMPILE_OPTIONS_LIST + OpenSSL_LIBRARIES + OpenSSL_LIBS + OpenSSL_LIBRARIES_TARGETS) + +# Find the real .lib/.a and add them to OpenSSL_LIBS and OpenSSL_LIBRARY_LIST +set(OpenSSL_LIBRARY_LIST ssl crypto dl pthread) +set(OpenSSL_LIB_DIRS "${CONAN_LIB_DIRS_OPENSSL}") + +# Gather all the libraries that should be linked to the targets (do not touch existing variables): +set(_OpenSSL_DEPENDENCIES "zlib::zlib") + +conan_package_library_targets("${OpenSSL_LIBRARY_LIST}" # libraries + "${OpenSSL_LIB_DIRS}" # package_libdir + "${_OpenSSL_DEPENDENCIES}" # deps + OpenSSL_LIBRARIES # out_libraries + OpenSSL_LIBRARIES_TARGETS # out_libraries_targets + "" # build_type + "OpenSSL") # package_name + +set(OpenSSL_LIBS ${OpenSSL_LIBRARIES}) + +# We need to add our requirements too +set(OpenSSL_LIBRARIES_TARGETS "${OpenSSL_LIBRARIES_TARGETS};zlib::zlib") +set(OpenSSL_LIBRARIES "${OpenSSL_LIBRARIES};zlib::zlib") + +set(CMAKE_MODULE_PATH "/home/dario/.conan/data/OpenSSL/1.0.2o/conan/stable/package/b781af3f476d0aa5070a0a35b544db7a3c193cc8/" ${CMAKE_MODULE_PATH}) +set(CMAKE_PREFIX_PATH "/home/dario/.conan/data/OpenSSL/1.0.2o/conan/stable/package/b781af3f476d0aa5070a0a35b544db7a3c193cc8/" ${CMAKE_PREFIX_PATH}) + +foreach(_BUILD_MODULE_PATH ${OpenSSL_BUILD_MODULES_PATHS}) + include(${_BUILD_MODULE_PATH}) +endforeach() + +if(NOT ${CMAKE_VERSION} VERSION_LESS "3.0") + # Target approach + if(NOT TARGET OpenSSL::OpenSSL) + add_library(OpenSSL::OpenSSL INTERFACE IMPORTED) + if(OpenSSL_INCLUDE_DIRS) + set_target_properties(OpenSSL::OpenSSL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OpenSSL_INCLUDE_DIRS}") + endif() + set_property(TARGET OpenSSL::OpenSSL PROPERTY INTERFACE_LINK_LIBRARIES + "${OpenSSL_LIBRARIES_TARGETS};${OpenSSL_LINKER_FLAGS_LIST}") + set_property(TARGET OpenSSL::OpenSSL PROPERTY INTERFACE_COMPILE_DEFINITIONS + ${OpenSSL_COMPILE_DEFINITIONS}) + set_property(TARGET OpenSSL::OpenSSL PROPERTY INTERFACE_COMPILE_OPTIONS + "${OpenSSL_COMPILE_OPTIONS_LIST}") + + # Library dependencies + include(CMakeFindDependencyMacro) + + if(NOT zlib_FOUND) + find_dependency(zlib REQUIRED) + else() + message(STATUS "Dependency zlib already found") + endif() + + endif() +endif() diff --git a/conanfile.txt b/conanfile.txt index a6c09d9fa..703260a39 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -6,4 +6,3 @@ gtest/1.8.1@bincrafters/stable [generators] cmake - diff --git a/src/cpp/test/crypto/TestKeyPairEd25519.cpp b/src/cpp/test/crypto/TestKeyPairEd25519.cpp index 314fb9cdc..51f714776 100644 --- a/src/cpp/test/crypto/TestKeyPairEd25519.cpp +++ b/src/cpp/test/crypto/TestKeyPairEd25519.cpp @@ -1,6 +1,6 @@ #include "TestPassphrase.h" -#include "../../Crypto/KeyPair.h" + #include "../../Crypto/KeyPairEd25519.h" #include "../../Crypto/Passphrase.h" #include "../../lib/DataTypeConverter.h" @@ -14,12 +14,12 @@ TEST_F(PassphraseTest, TestEd25519KeyPair) { auto word_indices = tr->getWordIndices(); auto key_pair_ed25519 = KeyPairEd25519::create(tr); - KeyPair key_pair; + //KeyPair key_pair; - key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); + //key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); - EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); - EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), key_pair.getPubkeyHex()); + //EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); + //EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), key_pair.getPubkeyHex()); //auto key_pair_old delete key_pair_ed25519; diff --git a/src/cpp/test/crypto/TestPassphrase.cpp b/src/cpp/test/crypto/TestPassphrase.cpp index 128a461f6..010353e17 100644 --- a/src/cpp/test/crypto/TestPassphrase.cpp +++ b/src/cpp/test/crypto/TestPassphrase.cpp @@ -10,7 +10,6 @@ #include "../../lib/DataTypeConverter.h" #include "../../Crypto/KeyPairEd25519.h" -#include "../../Crypto/KeyPair.h" @@ -170,10 +169,10 @@ TEST_F(PassphraseTest, createAndTransform) { EXPECT_EQ(word_indices[i], test_data_set.wordIndices[i]); } auto key_pair_ed25519 = KeyPairEd25519::create(tr); - KeyPair key_pair; - key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); - //EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), test_data_set.pubkeyHex); - EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); + //KeyPair key_pair; + //key_pair.generateFromPassphrase(test_data_set.passphrases[test_data_set.mnemonicType].data(), mnemonic); + EXPECT_EQ(DataTypeConverter::pubkeyToHex(key_pair_ed25519->getPublicKey()), test_data_set.pubkeyHex); + //EXPECT_EQ(key_pair.getPubkeyHex(), test_data_set.pubkeyHex); //auto key_pair_old delete key_pair_ed25519; From 91672701493db0e458b03e4fd933ef547b234ef8 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Thu, 8 Oct 2020 11:51:23 +0200 Subject: [PATCH 095/195] cmake update for windows --- CMakeLists.txt | 20 +++++++------------- README | 16 +++++++--------- windows_parse_proto.sh | 8 ++++---- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4275714dc..d5df00b87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,8 +101,11 @@ set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf") if(WIN32) - find_library(MYSQL_LIBRARIES mariadbclient.lib PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) + find_library(MYSQL_LIBRARIES mariadbclient PATHS "${MARIADB_CONNECTOR_PATH}/Release" REQUIRED) find_library(COMPILED_MARIADB_CLIENT_DEBUG mariadbclient PATHS "${MARIADB_CONNECTOR_PATH}/Debug" REQUIRED) + + find_library(CONAN_OPENSSL_SSL ssleay32 PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) + find_library(CONAN_OPENSSL_CRYPTO libeay32 PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(GRPC_PATH "${GRPC_PATH}/Debug") set(GRPC_ABSL_PATH "${GRPC_ABSL_PATH}/Debug") @@ -111,15 +114,6 @@ if(WIN32) set(GRPC_RE2_PATH "${GRPC_RE2_PATH}/Debug") set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}/Debug") - find_library(PROTOBUF_LIB_DEBUG libprotobufd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) - find_library(PROTOBUF_LIB_LITE_DEBUG libprotobuf-lited PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) - find_library(PROTOBUF_LIBC_DEBUG libprotocd PATHS ${GRPC_PROTOBUF_DEBUG_PATH} REQUIRED) - - set(PROTOBUF_DEBUG_LIBS - ${PROTOBUF_LIB_DEBUG} - ${PROTOBUF_LIB_LITE_DEBUG} - ${PROTOBUF_LIBC_DEBUG} - ) list(REMOVE_ITEM CONAN_LIBS "libeay32.lib") list(REMOVE_ITEM CONAN_LIBS "ssleay32.lib") @@ -128,6 +122,8 @@ if(WIN32) else (WIN32) find_library(MYSQL_LIBRARIES libmariadb.so PATHS ${MARIADB_CONNECTOR_PATH} REQUIRED) + find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) + find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}") list(REMOVE_ITEM CONAN_LIBS "ssl") @@ -138,10 +134,8 @@ endif(WIN32) # load same ssl version like used from poco -find_package(OpenSSL PATHS . NO_DEFAULT_PATH) +#find_package(OpenSSL PATHS . NO_DEFAULT_PATH) -find_library(CONAN_OPENSSL_SSL ssl PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) -find_library(CONAN_OPENSSL_CRYPTO crypto PATHS ${CONAN_LIB_DIRS_OPENSSL} REQUIRED NO_DEFAULT_PATH ) set(CONAN_OPENSSL_CUSTOM_LIBS ${CONAN_OPENSSL_SSL} diff --git a/README b/README index c6419d014..85f15134c 100644 --- a/README +++ b/README @@ -9,15 +9,6 @@ cmake -DWITH_SSL=OFF .. cd ../../../ -cd dependencies/grpc -mkdir build -cd build -cmake .. -make -# under windows build at least release for protoc.exe and grpc c++ plugin -cd ../../../ -./unix_parse_proto.sh - # get more dependencies with conan (need conan from https://conan.io/) mkdir build && cd build # // not used anymore @@ -29,3 +20,10 @@ conan install .. # build Makefile with cmake cmake .. +make grpc +# under windows build at least release for protoc.exe and grpc c++ plugin +cd ../ +./unix_parse_proto.sh +cd build +make + diff --git a/windows_parse_proto.sh b/windows_parse_proto.sh index 4c5d56d47..90497e6b8 100644 --- a/windows_parse_proto.sh +++ b/windows_parse_proto.sh @@ -5,15 +5,15 @@ fi if [ ! -d "./src/cpp/proto/gradido" ] ; then mkdir ./src/cpp/proto/gradido fi -PROTOC_PATH=./dependencies/grpc/_build/third_party/protobuf/Release -CPP_PLUGIN_PATH=./dependencies/grpc/_build/Release -$PROTOC_PATH/protoc --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto +PROTOC_PATH=build/bin +CPP_PLUGIN_PATH=build/bin +$PROTOC_PATH/protoc.exe --cpp_out=./src/cpp/proto --proto_path=./src/proto ./src/proto/gradido/*.proto if [ ! -d "./src/cpp/proto/hedera" ] ; then mkdir ./src/cpp/proto/hedera fi GOOGLE_PROTOBUF_INCLUDES=./dependencies/grpc/third_party/protobuf/src -$PROTOC_PATH/protoc --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto +$PROTOC_PATH/protoc.exe --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=./src/cpp/proto/hedera --grpc_out=./src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=./src/proto/hedera/hedera-protobuf/src/main/proto ./src/proto/hedera/hedera-protobuf/src/main/proto/*.proto From 7d7e2c544145cd4b7d77aa782d647064c9604a93 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Thu, 8 Oct 2020 17:19:30 +0200 Subject: [PATCH 096/195] merge updated production code with grpc code --- .../HTTPInterface/DecodeTransactionPage.cpp | 21 +++++++++---------- src/cpp/HTTPInterface/LoginPage.cpp | 2 +- src/cpp/SingletonManager/EmailManager.cpp | 4 ++-- src/cpp/controller/UserBackup.cpp | 1 + src/cpp/model/Session.cpp | 10 +++++++-- src/cpp/tasks/ProcessingTransaction.cpp | 6 +++--- src/cpp/tasks/ProcessingTransaction.h | 3 ++- src/cpsp/decodeTransaction.cpsp | 3 +-- src/cpsp/login.cpsp | 2 +- src/proto | 2 +- 10 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/cpp/HTTPInterface/DecodeTransactionPage.cpp b/src/cpp/HTTPInterface/DecodeTransactionPage.cpp index 4597672ca..c01d83a9f 100644 --- a/src/cpp/HTTPInterface/DecodeTransactionPage.cpp +++ b/src/cpp/HTTPInterface/DecodeTransactionPage.cpp @@ -222,8 +222,7 @@ void DecodeTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, auto creation = transactionBody.creation(); TransactionCreation creationObject("", creation); - auto receiver = creation.receiveramount(); - + auto receiver = creation.receiver(); char hex[65]; memset(hex, 0, 65); sodium_bin2hex(hex, 65, (const unsigned char*)receiver.pubkey().data(), receiver.pubkey().size()); @@ -238,36 +237,36 @@ void DecodeTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\n"; responseStream << "\t\t

    Creation

    \n"; responseStream << "\t\t"; -#line 121 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 120 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" if(!adminUser || user.isNull() || !user->getModel()) { responseStream << "\n"; responseStream << "\t\t

    pubkey: "; -#line 122 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 121 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" responseStream << ( hex ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 123 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 122 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t

    user:

    \n"; responseStream << "\t\t

    "; -#line 125 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 124 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" responseStream << ( user->getModel()->toHTMLString() ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 126 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 125 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t

    amount: "; -#line 127 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 126 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" responseStream << ( TransactionBase::amountToString(receiver.amount()) ); responseStream << " GDD

    \n"; responseStream << "\t\t

    target date: "; -#line 128 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 127 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" responseStream << ( creationObject.getTargetDateString() ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 129 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 128 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" } responseStream << "\n"; responseStream << "\t"; -#line 130 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 129 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" } responseStream << "\n"; responseStream << "
    \n"; // begin include footer.cpsp diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 7e71c9187..b264eda16 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -105,7 +105,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: } else { langCatalog = mSession->getLanguageCatalog(); } - UserStates user_state; + UserState user_state; try { user_state = mSession->loadUser(email, password); } catch (Poco::Exception& ex) { diff --git a/src/cpp/SingletonManager/EmailManager.cpp b/src/cpp/SingletonManager/EmailManager.cpp index 847887316..5760c8ee2 100644 --- a/src/cpp/SingletonManager/EmailManager.cpp +++ b/src/cpp/SingletonManager/EmailManager.cpp @@ -60,7 +60,7 @@ void EmailManager::addEmail(model::Email* email) { std::string log_message = "Email should be sended to: "; auto email_user = email->getUser(); if (email_user && email_user->getModel()) { - log_message += email_user->getModel()->getNameWithEmail(); + log_message += email_user->getModel()->getNameWithEmailHtml(); } else { log_message += ""; @@ -138,7 +138,7 @@ int EmailManager::ThreadFunction() std::string log_message = "Email sended to: "; auto email_user = email->getUser(); if (user_model) { - log_message += email_user->getModel()->getNameWithEmail(); + log_message += email_user->getModel()->getNameWithEmailHtml(); } else { log_message += ""; diff --git a/src/cpp/controller/UserBackup.cpp b/src/cpp/controller/UserBackup.cpp index 88bc3f682..9899fc58a 100644 --- a/src/cpp/controller/UserBackup.cpp +++ b/src/cpp/controller/UserBackup.cpp @@ -54,6 +54,7 @@ namespace controller { return mKeyPair; } mKeyPair = createGradidoKeyPair(); + return mKeyPair; } KeyPairEd25519* UserBackup::createGradidoKeyPair() diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 217414aec..fdf6afe8c 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -685,11 +685,17 @@ bool Session::startProcessingTransaction(const std::string& proto_message_base64 } } + Languages lang = LANG_DE; + if (!mNewUser.isNull()) { + lang = LanguageManager::languageFromString(mNewUser->getModel()->getLanguageKey()); + } + Poco::AutoPtr processorTask( new ProcessingTransaction( proto_message_base64, - DRMakeStringHash(mSessionUser->getEmail()), - mSessionUser->getLanguage()) + DRMakeStringHash(mSessionUser->getEmail().data()), + lang + ) ); if (autoSign && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) == ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) { if (processorTask->run() != 0) { diff --git a/src/cpp/tasks/ProcessingTransaction.cpp b/src/cpp/tasks/ProcessingTransaction.cpp index 3cf9905a8..33d259738 100644 --- a/src/cpp/tasks/ProcessingTransaction.cpp +++ b/src/cpp/tasks/ProcessingTransaction.cpp @@ -9,9 +9,9 @@ #include "../lib/DataTypeConverter.h" #include "../lib/JsonRequest.h" -ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang) +ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated/* = Poco::DateTime()*/) : mType(TRANSACTION_NONE), mProtoMessageBase64(proto_message_base64), mTransactionSpecific(nullptr), mUserEmailHash(userEmailHash), - mLang(lang) + mLang(lang), mTransactionCreated(transactionCreated) { mHashMutex.lock(); mHash = calculateHash(proto_message_base64); @@ -118,7 +118,7 @@ int ProcessingTransaction::run() if (mTransactionSpecific->prepare()) { getErrors(mTransactionSpecific); addError(new Error("ProcessingTransaction", "error preparing")); - reportErrorToCommunityServer(catalog->gettext("format error"), catalog->gettext("format of specific transaction not known, wrong proto version?"), std::to_string(mTransactionBody.created().seconds())); + reportErrorToCommunityServer(catalog->gettext("format error"), catalog->gettext("format of specific transaction not known, wrong proto version?"), Poco::DateTimeFormatter::format(mTransactionCreated, "%s")); unlock(); return -3; } diff --git a/src/cpp/tasks/ProcessingTransaction.h b/src/cpp/tasks/ProcessingTransaction.h index 916e54691..ee694857a 100644 --- a/src/cpp/tasks/ProcessingTransaction.h +++ b/src/cpp/tasks/ProcessingTransaction.h @@ -33,7 +33,7 @@ class ProcessingTransaction : public UniLib::controller::CPUTask, public Notific friend SigningTransaction; public: //! \param lang for error messages in user language - ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang); + ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated = Poco::DateTime()); virtual ~ProcessingTransaction(); int run(); @@ -70,6 +70,7 @@ protected: DHASH mUserEmailHash; Languages mLang; Poco::Mutex mHashMutex; + Poco::DateTime mTransactionCreated; private: }; diff --git a/src/cpsp/decodeTransaction.cpsp b/src/cpsp/decodeTransaction.cpsp index 89369ce8e..1416e8471 100644 --- a/src/cpsp/decodeTransaction.cpsp +++ b/src/cpsp/decodeTransaction.cpsp @@ -103,8 +103,7 @@ auto creation = transactionBody.creation(); TransactionCreation creationObject("", creation); - auto receiver = creation.receiveramount(); - + auto receiver = creation.receiver(); char hex[65]; memset(hex, 0, 65); sodium_bin2hex(hex, 65, (const unsigned char*)receiver.pubkey().data(), receiver.pubkey().size()); diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index 0f2a4d281..b2b091fef 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -81,7 +81,7 @@ } else { langCatalog = mSession->getLanguageCatalog(); } - UserStates user_state; + UserState user_state; try { user_state = mSession->loadUser(email, password); } catch (Poco::Exception& ex) { diff --git a/src/proto b/src/proto index 72e8fe7b7..ff412f735 160000 --- a/src/proto +++ b/src/proto @@ -1 +1 @@ -Subproject commit 72e8fe7b73a1aaf2d057d2fef59ade9268830008 +Subproject commit ff412f735667b30233c0ce00d461f209ac7dde7c From eb84c282988814e7c21be1e201b198269297ed36 Mon Sep 17 00:00:00 2001 From: Dario via Pythagoras Date: Thu, 8 Oct 2020 19:12:22 +0200 Subject: [PATCH 097/195] fix merge errors --- dependencies/mariadb-connector-c | 2 +- src/cpp/lib/JsonRequest.cpp | 90 -------------------------------- src/proto | 2 +- 3 files changed, 2 insertions(+), 92 deletions(-) diff --git a/dependencies/mariadb-connector-c b/dependencies/mariadb-connector-c index 1f7480118..159540fe8 160000 --- a/dependencies/mariadb-connector-c +++ b/dependencies/mariadb-connector-c @@ -1 +1 @@ -Subproject commit 1f7480118acfe12be9e356827aa30ae9b9eca9a7 +Subproject commit 159540fe8c8f30b281748fe8a1b79e8b17993a67 diff --git a/src/cpp/lib/JsonRequest.cpp b/src/cpp/lib/JsonRequest.cpp index 825d30f66..fa12de0b9 100644 --- a/src/cpp/lib/JsonRequest.cpp +++ b/src/cpp/lib/JsonRequest.cpp @@ -192,93 +192,3 @@ JsonRequestReturn JsonRequest::requestGRPCRelay(const Poco::Net::NameValueCollec return JSON_REQUEST_RETURN_OK; } -#include "Poco/JSON/Stringifier.h" -JsonRequestReturn JsonRequest::requestGRPCRelay(const Poco::Net::NameValueCollection& payload) -{ - static const char* functionName = "JsonRequest::requestGRPCRelay"; - Poco::JSON::Object requestJson; - - for (auto it = payload.begin(); it != payload.end(); it++) { - requestJson.set(it->first, it->second); - } - - // send post request via https - // 443 = HTTPS Default - // TODO: adding port into ServerConfig - try { - Profiler phpRequestTime; - Poco::Net::HTTPClientSession httpClientSession(mServerHost, mServerPort); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/hedera_rpc_relay/gRPCProxy.php"); - - request.setChunkedTransferEncoding(false); - std::ostream& requestStream = httpClientSession.sendRequest(request); - requestJson.stringify(requestStream); - - std::stringstream ss; - requestJson.stringify(ss); - auto f = fopen("grpc.txt", "wt"); - std::string grpc = ss.str(); - fwrite(grpc.data(), grpc.size(), 1, f); - fclose(f); - - Poco::Net::HTTPResponse response; - std::istream& request_stream = httpClientSession.receiveResponse(response); - - // debugging answer - - std::stringstream responseStringStream; - for (std::string line; std::getline(request_stream, line); ) { - responseStringStream << line << std::endl; - } - Poco::Logger& speedLog = Poco::Logger::get("SpeedLog"); - speedLog.information("[gRPC relay] php server time: %s", phpRequestTime.string()); - - // extract parameter from request - Poco::JSON::Parser jsonParser; - Poco::Dynamic::Var parsedJson; - try { - parsedJson = jsonParser.parse(responseStringStream.str()); - } - catch (Poco::Exception& ex) { - addError(new ParamError(functionName, "error parsing request answer grpc relay", ex.displayText().data())); - - std::string fileName = "response_grpc_"; - fileName += ".html"; - - FILE* f = fopen(fileName.data(), "wt"); - std::string responseString = responseStringStream.str(); - fwrite(responseString.data(), 1, responseString.size(), f); - fclose(f); - // */ - sendErrorsAsEmail(responseStringStream.str()); - return JSON_REQUEST_RETURN_PARSE_ERROR; - } - - Poco::JSON::Object object = *parsedJson.extract(); - auto state = object.get("state"); - std::string stateString = state.convert(); - if (stateString == "error") { - addError(new Error(functionName, "php server return error")); - if (!object.isNull("msg")) { - addError(new ParamError(functionName, "msg:", object.get("msg").convert().data())); - } - if (!object.isNull("details")) { - addError(new ParamError(functionName, "details:", object.get("details").convert().data())); - } - sendErrorsAsEmail(); - return JSON_REQUEST_RETURN_ERROR; - } - ss.clear(); - Poco::JSON::Stringifier::stringify(object, ss); - printf("json request result: %s\n", ss.str().data()); - } - catch (Poco::Exception& e) { - addError(new ParamError(functionName, "connect error to php server", e.displayText().data())); - sendErrorsAsEmail(); - return JSON_REQUEST_CONNECT_ERROR; - } - - - - return JSON_REQUEST_RETURN_OK; -} \ No newline at end of file diff --git a/src/proto b/src/proto index ff412f735..81a461566 160000 --- a/src/proto +++ b/src/proto @@ -1 +1 @@ -Subproject commit ff412f735667b30233c0ce00d461f209ac7dde7c +Subproject commit 81a461566e46d71533dc3e284fa075d7d68fd020 From e9000f51ccdd76e5fb65eb538182b848d5d3f874 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 12 Oct 2020 13:02:24 +0200 Subject: [PATCH 098/195] updates for windows build --- CMakeLists.txt | 13 ++++++++++++- src/proto | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac11cb377..d415b3f89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,9 +88,20 @@ conan_basic_setup() add_executable(Gradido_LoginServer ${LOCAL_SRCS}) set(CLIENT_PLUGIN_DIALOG OFF) -set(CLIENT_PLUGIN_client_ed25519 OFF) set(CLIENT_PLUGIN_MYSQL_CLEAR_PASSWORD OFF) set(CLIENT_PLUGIN_REMOTE_IO OFF) +IF(WIN32) +#set(CLIENT_PLUGIN_caching_sha2_password OFF) +set(CLIENT_PLUGIN_CACHING_SHA2_PASSWORD OFF) +set(CLIENT_PLUGIN_SHA256_PASSWORD OFF) +set(CLIENT_PLUGIN_AUTH_GSSAPI_CLIENT OFF) +set(CLIENT_PLUGIN_PVIO_NPIPE STATIC) +set(CLIENT_PLUGIN_PVIO_SHMEM STATIC) +set(CLIENT_PLUGIN_CLIENT_ED25519 OFF) +ELSEIF() +set(CLIENT_PLUGIN_client_ed25519 OFF) +ENDIF() + set(WITH_SSL OFF) add_subdirectory("dependencies/mariadb-connector-c") diff --git a/src/proto b/src/proto index 81a461566..ff412f735 160000 --- a/src/proto +++ b/src/proto @@ -1 +1 @@ -Subproject commit 81a461566e46d71533dc3e284fa075d7d68fd020 +Subproject commit ff412f735667b30233c0ce00d461f209ac7dde7c From c9874394b340b521c7af56a7850920fb886ca639 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 12 Oct 2020 14:53:03 +0200 Subject: [PATCH 099/195] move gradido transaction wrapper classes in own folder and sub-namespace under model --- CMakeLists.txt | 5 +- .../HTTPInterface/CheckTransactionPage.cpp | 4 +- .../HTTPInterface/DecodeTransactionPage.cpp | 49 +++--- src/cpp/HTTPInterface/UserUpdateGroupPage.cpp | 63 ++++---- src/cpp/MySQL/Connector.cpp | 3 - src/cpp/model/TransactionBase.cpp | 25 --- src/cpp/model/TransactionCreation.h | 39 ----- src/cpp/model/TransactionTransfer.h | 51 ------ src/cpp/model/UserPassphrase.cpp | 0 src/cpp/model/UserPassphrase.h | 0 src/cpp/model/email/Email.cpp | 4 +- src/cpp/model/gradido/TransactionBase.cpp | 30 ++++ src/cpp/model/{ => gradido}/TransactionBase.h | 26 +-- src/cpp/model/gradido/TransactionCreation.cpp | 67 ++++++++ src/cpp/model/gradido/TransactionCreation.h | 45 ++++++ src/cpp/model/gradido/TransactionTransfer.cpp | 148 ++++++++++++++++++ src/cpp/model/gradido/TransactionTransfer.h | 57 +++++++ src/cpp/tasks/ProcessingTransaction.cpp | 16 +- src/cpp/tasks/ProcessingTransaction.h | 18 ++- src/cpp/tasks/SigningTransaction.h | 1 - src/cpsp/checkTransaction.cpsp | 4 +- src/cpsp/decodeTransaction.cpsp | 9 +- src/cpsp/header_navi_chr.cpsp | 4 +- src/cpsp/userUpdateGroup.cpsp | 2 +- 24 files changed, 457 insertions(+), 213 deletions(-) delete mode 100644 src/cpp/model/TransactionBase.cpp delete mode 100644 src/cpp/model/TransactionCreation.h delete mode 100644 src/cpp/model/TransactionTransfer.h delete mode 100644 src/cpp/model/UserPassphrase.cpp delete mode 100644 src/cpp/model/UserPassphrase.h create mode 100644 src/cpp/model/gradido/TransactionBase.cpp rename src/cpp/model/{ => gradido}/TransactionBase.h (52%) create mode 100644 src/cpp/model/gradido/TransactionCreation.cpp create mode 100644 src/cpp/model/gradido/TransactionCreation.h create mode 100644 src/cpp/model/gradido/TransactionTransfer.cpp create mode 100644 src/cpp/model/gradido/TransactionTransfer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d415b3f89..22cfac879 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp") FILE(GLOB MODEL_TABLE "src/cpp/model/table/*.h" "src/cpp/model/table/*.cpp") FILE(GLOB MODEL_EMAIL "src/cpp/model/email/*.h" "src/cpp/model/email/*.cpp") FILE(GLOB MODEL_HEDERA "src/cpp/model/hedera/*.h" "src/cpp/model/hedera/*.cpp") +FILE(GLOB MODEL_GRADIDO "src/cpp/model/gradido/*.h" "src/cpp/model/gradido/*.cpp") FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp") FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h") FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h") @@ -48,7 +49,8 @@ FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controll SET(LOCAL_SRCS ${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} - ${JSONInterface} ${CRYPTO} ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_HEDERA} + ${JSONInterface} ${CRYPTO} + ${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_HEDERA} ${MODEL_GRADIDO} ${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS} ${PROTO_GRADIDO} ${PROTO_HEDERA} ) @@ -68,6 +70,7 @@ if(MSVC) source_group("model\\table" FILES ${MODEL_TABLE}) source_group("model\\email" FILES ${MODEL_EMAIL}) source_group("model\\hedera" FILES ${MODEL_HEDERA}) + source_group("model\\gradido" FILES ${MODEL_GRADIDO}) source_group("model" FILES ${MODEL}) source_group("mysql" FILES ${MYSQL}) source_group("SingletonManager" FILES ${SINGLETON_MANAGER}) diff --git a/src/cpp/HTTPInterface/CheckTransactionPage.cpp b/src/cpp/HTTPInterface/CheckTransactionPage.cpp index b50f1c69d..ce521c7e2 100644 --- a/src/cpp/HTTPInterface/CheckTransactionPage.cpp +++ b/src/cpp/HTTPInterface/CheckTransactionPage.cpp @@ -10,8 +10,8 @@ #include "../SingletonManager/SessionManager.h" #include "../SingletonManager/SingletonTaskObserver.h" #include "../SingletonManager/EmailManager.h" -#include "../model/TransactionCreation.h" -#include "../model/TransactionTransfer.h" +#include "../model/gradido/TransactionCreation.h" +#include "../model/gradido/TransactionTransfer.h" #include "Poco/Thread.h" diff --git a/src/cpp/HTTPInterface/DecodeTransactionPage.cpp b/src/cpp/HTTPInterface/DecodeTransactionPage.cpp index c01d83a9f..f93d1e3bf 100644 --- a/src/cpp/HTTPInterface/DecodeTransactionPage.cpp +++ b/src/cpp/HTTPInterface/DecodeTransactionPage.cpp @@ -5,14 +5,14 @@ #include "Poco/DeflatingStream.h" -#line 7 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\decodeTransaction.cpsp" #include "sodium.h" #include "../proto/gradido/TransactionBody.pb.h" #include "../controller/User.h" -#include "../model/TransactionBase.h" -#include "../model/TransactionCreation.h" -#line 1 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header_old.cpsp" +#include "../model/gradido/TransactionBase.h" +#include "../model/gradido/TransactionCreation.h" +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" #include "../ServerConfig.h" @@ -31,7 +31,7 @@ void DecodeTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 14 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\decodeTransaction.cpsp" +#line 14 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\decodeTransaction.cpsp" const char* pageName = "Decode Transaction"; proto::gradido::TransactionBody transactionBody; @@ -99,12 +99,12 @@ void DecodeTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\n"; responseStream << "\n"; responseStream << "Gradido Login Server: "; -#line 9 "D:\\code\\gradido\\gradido_login_server_grpc\\src\\cpsp\\header_old.cpsp" +#line 9 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" responseStream << ( pageName ); responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; -#line 133 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; @@ -233,7 +252,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << "\t\t\t\t
    Aktionen
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) { auto hedera_topic_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/topic?action=getTopicInfos&topic_id=" + std::to_string(hedera_topic_model->getID()); @@ -245,58 +264,69 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: } else if((hedera_topic_model->getCurrentTimeout() - Poco::DateTime()) < Poco::Timespan(2,0,0,0,0)) { timeout_color = "orange-color"; } + std::string topic_hedera_id_string = ""; + auto topic_hedera_id = (*it)->getTopicHederaId(); + if(!topic_hedera_id.isNull()) { + topic_hedera_id_string = topic_hedera_id->getModel()->toString(); + } + responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 168 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" - responseStream << ( (*it)->getTopicHederaId()->getModel()->toString() ); +#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + responseStream << ( topic_hedera_id_string ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 194 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( hedera_topic_model->getName() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(renew_account_model->getNetworkType()) ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 196 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( renew_account_model->getBalanceString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 197 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( hedera_topic_model->getAutoRenewPeriodString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 173 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( hedera_topic_model->getGroupId() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( hedera_topic_model->getCurrentTimeoutString() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 175 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( hedera_topic_model->getSequenceNumber() ); responseStream << "
    \n"; responseStream << "\t\t\t\t\t
    "; -#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" responseStream << ( hedera_topic_model->getUpdatedString() ); responseStream << "
    \n"; - responseStream << "\t\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t
    "; +#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + if(!topic_hedera_id.isNull()) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" + } responseStream << "\n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t"; -#line 183 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" +#line 209 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; @@ -305,72 +335,72 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << "\t
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\n"; @@ -401,7 +431,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: // end include footer.cpsp responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; + responseStream << "\n"; responseStream << " + \n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; responseStream << "\n"; @@ -329,6 +353,7 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "
    \n"; responseStream << "
    \n"; responseStream << " \n"; @@ -344,10 +369,27 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << " \n"; + responseStream << " \n"; responseStream << " \n"; responseStream << " \n"; @@ -374,7 +427,7 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, #line 37 "F:\\Gradido\\gradido_login_server_production\\src\\cpsp\\header_navi_chr.cpsp" //responseStream << ( ServerConfig::g_php_serverPath ); #line 37 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_navi_chr.cpsp" - responseStream << ( user->getGroupBaseUrl() ); + responseStream << ( community_server_base_path ); responseStream << "state-balances/overview\" class=\"\">getGroupBaseUrl() ); + responseStream << ( community_server_base_path ); responseStream << "dashboard/index\" class=\"\">homeStartseite\n"; responseStream << "
  • getGroupBaseUrl() ); + responseStream << ( community_server_base_path ); responseStream << "transaction-send-coins/create\" class=\"\">account_balanceÜberweisung
  • \n"; responseStream << "
  • \n"; responseStream << "
  • getGroupBaseUrl() ); + responseStream << ( community_server_base_path ); responseStream << "\" class=\"\">Startseite
  • \n"; responseStream << " \n"; responseStream << "
  • "; @@ -421,6 +474,7 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "
  • "; // end include header_navi_chr.cpsp responseStream << "\n"; +<<<<<<< HEAD /* #line 126 "F:\\Gradido\\gradido_login_server_production\\src\\cpsp\\checkTransaction.cpsp" if(transaction_finalize_run) { responseStream << "\n"; @@ -503,163 +557,163 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << " "; #line 154 "F:\\Gradido\\gradido_login_server_production\\src\\cpsp\\checkTransaction.cpsp" */ -#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp"´ responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t\n"; responseStream << "\t"; -#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(sumTransactions == 0) { responseStream << "\n"; responseStream << "\t\t"; -#line 196 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 204 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Es gibt zurzeit keine Transaktionen zum bestätigen") ); responseStream << "\n"; responseStream << " "; -#line 197 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 205 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\t\n"; responseStream << "\t\t

    "; -#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( sumTransactions ); responseStream << " "; -#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Transaktionen warten darauf bestätigt zu werden.") ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(skip_count > 0) { responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 208 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( skip_count ); responseStream << " "; -#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 208 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Transaktionen übersprungen.") ); responseStream << "

    \n"; responseStream << "\t\t"; -#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 209 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t"; -#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 210 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "
    \n"; responseStream << "
    \n"; responseStream << "\t
    \n"; responseStream << "\t\t

    "; -#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Transaktion Unterzeichnen") ); responseStream << "

    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t"; -#line 209 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(state == PAGE_TRANSACTION_TRANSFER) { auto transferTransaction = transaction_body->getTransferTransaction(); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 212 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 220 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Überweisung") ); responseStream << "

    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t"; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Konto") ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Gradido") ); responseStream << "\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t "; -#line 218 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 226 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" for(int i = 0; i < transferTransaction->getKontoTableSize(); i++) { responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if((i+1) % 2 == 0) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 229 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 231 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t\t"; -#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 232 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( transferTransaction->getKontoNameCell(i) ); responseStream << "\n"; responseStream << "\t\t\t\t\t\t"; -#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 233 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( transferTransaction->getAmountCell(i) ); responseStream << "\n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t "; -#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 235 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t "; -#line 229 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 237 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_TRANSACTION_CREATION == state) { auto creationTransaction = transaction_body->getCreationTransaction(); auto transactionUser = creationTransaction->getUser(); responseStream << "\n"; responseStream << "\t\t\t\t

    "; -#line 233 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 241 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Schöpfung") ); responseStream << "

    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 236 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Konto") ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 237 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Zieldatum") ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Gradido") ); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 241 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 249 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!transactionUser.isNull()) { auto user_model = transactionUser->getModel(); responseStream << "\n"; responseStream << "\t\t\t\t\t\t"; -#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getFirstName() ); responseStream << " "; -#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getLastName() ); responseStream << " <"; -#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getEmail() ); responseStream << ">\n"; responseStream << "\t\t\t\t\t"; -#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 253 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t\t0x"; -#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( creationTransaction->getPublicHex() ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 255 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 256 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( creationTransaction->getTargetDateString() ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 249 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 257 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( creationTransaction->getAmountString() ); responseStream << " GDD\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t "; -#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 260 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_TRANSACTION_GROUP_ADD_MEMBER == state) { auto groupMemberUpdateTransaction = transaction_body->getGroupMemberUpdate(); auto groups = controller::Group::load(groupMemberUpdateTransaction->getTargetGroupAlias()); @@ -674,112 +728,112 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, } responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Benutzer zu einer Gruppe hinzufügen") ); responseStream << "

    \n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t

    "; -#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 275 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!user.isNull()) { responseStream << "\n"; responseStream << "\t\t\t\t\tBenutzer: "; -#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 276 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user->getEmailWithNames() ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\tAccount public key: "; -#line 270 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 278 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( groupMemberUpdateTransaction->getPublicKeyHex() ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 271 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 279 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "

    \n"; responseStream << "\t\t\t\t"; -#line 272 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!group_model.isNull()) { responseStream << "\n"; responseStream << "\t\t\t\t\t

    "; -#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Gruppe") ); responseStream << ":

    \n"; responseStream << "\t\t\t\t\t
      \n"; responseStream << "\t\t\t\t\t\t
    • "; -#line 275 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 283 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Name") ); responseStream << ": "; -#line 275 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 283 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getName() ); responseStream << "
    • \n"; responseStream << "\t\t\t\t\t\t
    • "; -#line 276 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 284 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Alias") ); responseStream << ": "; -#line 276 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 284 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getAlias() ); responseStream << "
    • \n"; responseStream << "\t\t\t\t\t\t
    • "; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 285 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Url") ); responseStream << ": getUrl() ); responseStream << "/pages/visitor\" target=\"_blank\">"; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 285 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getUrl() ); responseStream << "
    • \n"; responseStream << "\t\t\t\t\t\t
    • "; -#line 278 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getDescription() ); responseStream << "
    • \n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t"; -#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 288 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Unbekannte Gruppe") ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 282 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 283 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 291 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Es haben bereits ") ); -#line 283 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 291 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( std::to_string(transaction->getSignCount()) ); -#line 283 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 291 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext(" unterzeichnet") ); responseStream << "\n"; responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t \n"; responseStream << "\t\t\t "; -#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 294 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_USER_DATA_CORRUPTED == state) { responseStream << "\n"; responseStream << "\t\t\t\t

    "; -#line 287 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 295 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Es gibt ein Problem mit deinen gespeicherten Daten, bitte wende dich an den")); responseStream << "getAdminReceiver()); responseStream << "?subject=Corrupt User Data&body=Hallo Dario,%0D%0A%0D%0Ameine Benutzer Daten sind korrupt.%0D%0Akannst du das prüfen?%0D%0A%0D%0AMit freundlichen Grüßen%0D%0A\">"; -#line 287 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 295 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << (gettext("Support") ); responseStream << "

    \n"; responseStream << "\t\t\t "; -#line 288 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 296 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t "; -#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(PAGE_NO_TRANSACTIONS == state) { responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 298 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Zurück") ); responseStream << "\n"; responseStream << "\t\t\t "; -#line 291 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 299 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; @@ -787,7 +841,7 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 305 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getNameWithEmailHtml() ); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; @@ -798,62 +852,62 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 305 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 313 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( memo ); responseStream << "\n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 309 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 317 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(transaction) { responseStream << "\n"; responseStream << "\t\t\t\t\t\tgetModel()->getID() ); responseStream << "\">\n"; responseStream << "\t\t\t\t\t"; -#line 311 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 319 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 313 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 321 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!account_user->hasPassword()) { responseStream << "\n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t\t \n"; responseStream << "\t\t\t\t\t\t \n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 318 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 326 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 319 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 327 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(PAGE_USER_DATA_CORRUPTED != state && user_model->isEmailChecked()) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 324 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 332 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 325 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 333 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(transaction_removeable) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; @@ -870,21 +924,21 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 330 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 338 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 335 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 343 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t"; -#line 337 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 345 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 816bc0179..4b373ca67 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -128,10 +128,9 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: } getErrors(mSession); - auto uri_start = request.serverParams().getServerName(); auto lastExternReferer = mSession->getLastReferer(); - printf("user_state: %d, uri_start: %s\n", user_state, uri_start); + //printf("user_state: %d\n", user_state); switch(user_state) { case USER_EMPTY: @@ -286,11 +285,11 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
    "; // end include header.cpsp responseStream << "\n"; -#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 197 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\n"; responseStream << "
    \n"; @@ -324,22 +323,22 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "\n"; responseStream << "
    \n"; responseStream << "\t\t
    \n"; responseStream << "\t\t\tgettext("E-Mail") ); responseStream << "\" value=\""; -#line 204 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( presetEmail ); responseStream << "\"/>\n"; responseStream << "\t\t\tgettext("Password") ); responseStream << "\" />\n"; responseStream << "\t\t \n"; responseStream << "\t\t
    \n"; @@ -347,7 +346,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
    \n"; responseStream << "
    \n"; responseStream << "\t

    "; -#line 211 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 210 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("You haven't any account yet? Please follow the link to create one.") ); responseStream << "

    \n"; responseStream << "\t \n"; responseStream << "\t\t\t"; -#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 212 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("Create New Account") ); responseStream << "\n"; responseStream << "\t\t \n"; responseStream << "\t
    \n"; responseStream << "\t\t\n"; diff --git a/src/cpsp/checkTransaction.cpsp b/src/cpsp/checkTransaction.cpsp index 16f2f2d15..981c391c5 100644 --- a/src/cpsp/checkTransaction.cpsp +++ b/src/cpsp/checkTransaction.cpsp @@ -39,6 +39,11 @@ enum PageState { int skip_count = 0; int pending_task_id = 0; + std::string community_server_base_path = ServerConfig::g_php_serverPath; + if(user_model->getGroupId() != 0) { + community_server_base_path = user->getGroupBaseUrl(); + } + PageState state = PAGE_NO_TRANSACTIONS; if(!user_model->isEmailChecked()) { @@ -250,7 +255,7 @@ enum PageState { } else if(!account_user->getModel()->getGroupId()) { response.redirect(getBaseUrl() + "/userUpdateGroup"); } else { - response.redirect(account_user->getGroupBaseUrl() + "state-balances/overview"); + response.redirect(account_user->getGroupBaseUrl() + "/state-balances/overview"); } return; } @@ -266,7 +271,10 @@ enum PageState { switch(transactionType) { case model::gradido::TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; case model::gradido::TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; - case model::gradido::TRANSACTION_GROUP_MEMBER_UPDATE: state = PAGE_TRANSACTION_GROUP_ADD_MEMBER; break; + case model::gradido::TRANSACTION_GROUP_MEMBER_UPDATE: + state = PAGE_TRANSACTION_GROUP_ADD_MEMBER; + //community_server_base_path + break; } } diff --git a/src/cpsp/header_navi_chr.cpsp b/src/cpsp/header_navi_chr.cpsp index 1feea9912..279a88da2 100644 --- a/src/cpsp/header_navi_chr.cpsp +++ b/src/cpsp/header_navi_chr.cpsp @@ -5,10 +5,10 @@ Gradido Login Server: <%= pageName %> - - - - + + + + @@ -16,16 +16,16 @@
    \n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 326 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 329 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(transaction) { responseStream << "\n"; responseStream << "\t\t\t\t\t\tgetModel()->getID() ); responseStream << "\">\n"; responseStream << "\t\t\t\t\t"; -#line 328 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 331 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 330 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 333 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!account_user->hasPassword()) { responseStream << "\n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t\t \n"; responseStream << "\t\t\t\t\t\t \n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t"; -#line 335 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 338 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 336 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 339 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(enableSign && !hasErrors) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 341 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 344 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 342 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 345 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(transaction_removeable) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; @@ -936,21 +946,21 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t\t\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 347 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 350 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 352 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 355 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t"; -#line 354 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 357 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t
    \n"; responseStream << "\t
    \n"; diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 0f14df37e..887768b58 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -67,7 +67,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: if(!form.empty()) { caller_uri = form.get("caller_uri", ""); - printf("form.get: caller_uri: %s\n", caller_uri.data()); + //printf("form.get: caller_uri: %s\n", caller_uri.data()); bool langUpdatedByBtn = false; auto langBtn = form.get("lang", ""); @@ -116,11 +116,12 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: } else { langCatalog = mSession->getLanguageCatalog(); */ - if(mSession) { + + /*if(mSession) { printf("start with session: %d\n", mSession->getHandle()); } else { printf("start without session\n"); - } + }*/ if(!mSession) { mSession = sm->getNewSession(); @@ -147,7 +148,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: } } - printf("after session: caller_uri: %s\n", caller_uri.data()); + //printf("after session: caller_uri: %s\n", caller_uri.data()); if(email != "" && password != "") { diff --git a/src/cpp/model/gradido/GroupMemberUpdate.cpp b/src/cpp/model/gradido/GroupMemberUpdate.cpp index 1a665445c..145e1e97a 100644 --- a/src/cpp/model/gradido/GroupMemberUpdate.cpp +++ b/src/cpp/model/gradido/GroupMemberUpdate.cpp @@ -2,6 +2,7 @@ #include "../../Crypto/KeyPairEd25519.h" #include "../../controller/Group.h" #include "../../SingletonManager/SessionManager.h" +#include "../../lib/JsonRequest.h" namespace model { namespace gradido { @@ -125,6 +126,9 @@ namespace model { // write new group_id in user table user_model->setGroupId(group_model->getID()); user_model->updateIntoDB("group_id", group_model->getID()); + + JsonRequest request(group_model->getUrl(), 443); + request.request("addUser", user->getJson()); printf("[GroupMemberUpdate::transactionAccepted] finished\n"); } diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index 6fa4b1446..3e5dad767 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -105,7 +105,7 @@ namespace model { return result; } - std::vector> Transaction::createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo) + std::vector> Transaction::createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo, bool inbound/* = true*/) { std::vector> results; auto em = ErrorManager::getInstance(); @@ -140,12 +140,13 @@ namespace model { Poco::AutoPtr topic_group; // default constructor set it to now Poco::Timestamp pairedTransactionId; - for (int i = 0; i < 2; i++) { - if (0 == i) { + // create only inbound transaction, and outbound before sending to hedera + //for (int i = 0; i < 1; i++) { + if (inbound) { transaction_group = receiverGroup; topic_group = sender_group; } - else { + else if(!inbound) { transaction_group = sender_group; topic_group = receiverGroup; } @@ -157,7 +158,7 @@ namespace model { return results; } if (transaction_group.isNull()) { - em->addError(new ParamError(function_name, "transaction group is zero, i:", i)); + em->addError(new ParamError(function_name, "transaction group is zero, inbound", inbound)); em->sendErrorsAsEmail(); return results; } @@ -166,12 +167,14 @@ namespace model { Poco::AutoPtr transaction = new Transaction(body); transaction->getModel()->setHederaId(topic_id->getModel()->getID()); results.push_back(transaction); - } + // } } + for (auto it = results.begin(); it != results.end(); it++) { (*it)->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER); PendingTasksManager::getInstance()->addTask(*it); } + return results; } @@ -308,6 +311,13 @@ namespace model { // check if enough signatures exist for next step if (getSignCount() >= mTransactionBody->getTransactionBase()->getMinSignatureCount()) { + if (getTransactionBody()->isTransfer()) { + auto transfer = getTransactionBody()->getTransferTransaction(); + if (transfer->isInbound()) { + auto transaction = transfer->createOutbound(getTransactionBody()->getMemo()); + transaction->sign(user); + } + } UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr(this, true))); transaction_send_task->scheduleTask(transaction_send_task); } @@ -657,7 +667,22 @@ namespace model { int SendTransactionTask::run() { - auto result = mTransaction->runSendTransaction(); + int result = 1; + // if transfer inbound, create also transfer outbound + /*if (mTransaction->getTransactionBody()->isTransfer()) { + auto transfer = mTransaction->getTransactionBody()->getTransferTransaction(); + if (transfer->isInbound()) { + auto outbound = transfer->createOutbound(mTransaction->getTransactionBody()->getMemo()); + if (outbound.isNull()) { result = -1;} + + result = outbound->runSendTransaction(); + } + } + if (result != 1) { + mTransaction->deleteFromDB(); + return 0; + }*/ + result = mTransaction->runSendTransaction(); printf("[SendTransactionTask::run] result: %d\n", result); // delete because of error if (-1 == result) { diff --git a/src/cpp/model/gradido/Transaction.h b/src/cpp/model/gradido/Transaction.h index ee27a9719..c135fd89f 100644 --- a/src/cpp/model/gradido/Transaction.h +++ b/src/cpp/model/gradido/Transaction.h @@ -30,7 +30,7 @@ namespace model { static Poco::AutoPtr createGroupMemberUpdate(Poco::AutoPtr user, Poco::AutoPtr group); //! \brief transfer //! \return for cross group transaction return two transactions - static std::vector> createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo); + static std::vector> createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo, bool inbound = true); //! \brief creation transaction static Poco::AutoPtr createCreation(Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate, const std::string& memo); static Poco::AutoPtr load(model::table::PendingTask* dbModel); @@ -60,6 +60,7 @@ namespace model { std::string getTransactionAsJson(bool replaceBase64WithHex = false); + protected: diff --git a/src/cpp/model/gradido/TransactionTransfer.cpp b/src/cpp/model/gradido/TransactionTransfer.cpp index 2837e1715..26442a4a1 100644 --- a/src/cpp/model/gradido/TransactionTransfer.cpp +++ b/src/cpp/model/gradido/TransactionTransfer.cpp @@ -1,4 +1,5 @@ #include "TransactionTransfer.h" +#include "Transaction.h" namespace model { namespace gradido { @@ -65,61 +66,61 @@ namespace model { Poco::ScopedLock _lock(mWorkMutex); const static char functionName[] = { "TransactionTransfer::prepare" }; - mKontoTable.reserve(2); + mKontoTable.reserve(2); - //auto receiverAmount = mProtoTransfer.receiveramount(); - //auto senderAmount + proto::gradido::TransferAmount* sender = nullptr; + std::string* receiver_pubkey = nullptr; + if (mProtoTransfer.has_local()) { + auto local_transfer = mProtoTransfer.local(); + sender = local_transfer.mutable_sender(); + receiver_pubkey = local_transfer.mutable_receiver(); + return prepare(sender, receiver_pubkey); + } + else if (mProtoTransfer.has_inbound()) { + auto inbound_transfer = mProtoTransfer.inbound(); + sender = inbound_transfer.mutable_sender(); + receiver_pubkey = inbound_transfer.mutable_receiver(); + return prepare(sender, receiver_pubkey); + } + else if (mProtoTransfer.has_outbound()) { + auto outbound_transfer = mProtoTransfer.outbound(); + sender = outbound_transfer.mutable_sender(); + receiver_pubkey = outbound_transfer.mutable_receiver(); + return prepare(sender, receiver_pubkey); + } + return -1; + } + + int TransactionTransfer::prepare(proto::gradido::TransferAmount* sender, std::string* receiver_pubkey) + { + assert(sender && receiver_pubkey); char pubkeyHexTemp[65]; + auto sender_pubkey = sender->pubkey(); + auto amount = sender->amount(); + auto sender_user = controller::User::create(); + auto receiver_user = controller::User::create(); - if (mProtoTransfer.has_local()) - { - auto local_transfer = mProtoTransfer.local(); - auto sender = local_transfer.sender(); - auto sender_pubkey = sender.pubkey(); - auto receiver_pubkey = local_transfer.receiver(); - auto amount = sender.amount(); - auto sender_user = controller::User::create(); - auto receiver_user = controller::User::create(); - - if (!sender_user->load((const unsigned char*)sender_pubkey.data())) { - sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)sender_pubkey.data(), sender_pubkey.size()); - mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, amount, true)); - } - else { - mKontoTable.push_back(KontoTableEntry(sender_user->getModel(), amount, true)); - } - - if (!receiver_user->load((const unsigned char*)receiver_pubkey.data())) { - sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)receiver_pubkey.data(), receiver_pubkey.size()); - mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, amount, false)); - } - else { - mKontoTable.push_back(KontoTableEntry(receiver_user->getModel(), amount, false)); - } - mMinSignatureCount = 1; - auto mm = MemoryManager::getInstance(); - auto pubkey_copy = mm->getFreeMemory(KeyPairEd25519::getPublicKeySize()); - memcpy(*pubkey_copy, sender_pubkey.data(), KeyPairEd25519::getPublicKeySize()); - mRequiredSignPublicKeys.push_back(pubkey_copy); - } - - - // TODO: add version for group transfer - - - /* - mReceiverUser = new User(receiverPublic.data()); - getErrors(mReceiverUser); - if (mReceiverUser->getUserState() == USER_EMPTY) { - sodium_bin2hex(mReceiverPublicHex, 65, (const unsigned char*)receiverPublic.data(), receiverPublic.size()); - delete mReceiverUser; - mReceiverUser = nullptr; + if (!sender_user->load((const unsigned char*)sender_pubkey.data())) { + sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)sender_pubkey.data(), sender_pubkey.size()); + mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, amount, true)); } else { - memcpy(mReceiverPublicHex, mReceiverUser->getPublicKeyHex().data(), 64); + mKontoTable.push_back(KontoTableEntry(sender_user->getModel(), amount, true)); } - //*/ + + if (!receiver_user->load((const unsigned char*)receiver_pubkey->data())) { + sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)receiver_pubkey->data(), receiver_pubkey->size()); + mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, amount, false)); + } + else { + mKontoTable.push_back(KontoTableEntry(receiver_user->getModel(), amount, false)); + } + mMinSignatureCount = 1; + auto mm = MemoryManager::getInstance(); + auto pubkey_copy = mm->getFreeMemory(KeyPairEd25519::getPublicKeySize()); + memcpy(*pubkey_copy, sender_pubkey.data(), KeyPairEd25519::getPublicKeySize()); + mRequiredSignPublicKeys.push_back(pubkey_copy); mIsPrepared = true; return 0; @@ -127,12 +128,42 @@ namespace model { TransactionValidation TransactionTransfer::validate() { + Poco::ScopedLock _lock(mWorkMutex); static const char function_name[] = "TransactionTransfer::validate"; - if (!mProtoTransfer.has_local()) { + /*if (!mProtoTransfer.has_local()) { addError(new Error(function_name, "only local currently implemented")); return TRANSACTION_VALID_CODE_ERROR; + }*/ + proto::gradido::TransferAmount* sender = nullptr; + std::string* receiver_pubkey = nullptr; + if (mProtoTransfer.has_local()) { + auto local_transfer = mProtoTransfer.local(); + sender = local_transfer.mutable_sender(); + receiver_pubkey = local_transfer.mutable_receiver(); + return validate(sender, receiver_pubkey); } - auto amount = mProtoTransfer.local().sender().amount(); + else if (mProtoTransfer.has_inbound()) { + auto inbound_transfer = mProtoTransfer.inbound(); + sender = inbound_transfer.mutable_sender(); + receiver_pubkey = inbound_transfer.mutable_receiver(); + return validate(sender, receiver_pubkey); + } + else if (mProtoTransfer.has_outbound()) { + auto outbound_transfer = mProtoTransfer.outbound(); + sender = outbound_transfer.mutable_sender(); + receiver_pubkey = outbound_transfer.mutable_receiver(); + return validate(sender, receiver_pubkey); + } + + return TRANSACTION_VALID_CODE_ERROR; + } + + TransactionValidation TransactionTransfer::validate(proto::gradido::TransferAmount* sender, std::string* receiver_pubkey) + { + assert(sender && receiver_pubkey); + + static const char function_name[] = "TransactionTransfer::validate"; + auto amount = sender->amount(); if (0 == amount) { addError(new Error(function_name, "amount is empty")); return TRANSACTION_VALID_INVALID_AMOUNT; @@ -141,15 +172,56 @@ namespace model { addError(new Error(function_name, "negative amount")); return TRANSACTION_VALID_INVALID_AMOUNT; } - if (mProtoTransfer.local().receiver().size() != KeyPairEd25519::getPublicKeySize()) { + if (receiver_pubkey->size() != KeyPairEd25519::getPublicKeySize()) { addError(new Error(function_name, "invalid size of receiver pubkey")); return TRANSCATION_VALID_INVALID_PUBKEY; } - if (mProtoTransfer.local().sender().pubkey().size() != KeyPairEd25519::getPublicKeySize()) { + if (sender->pubkey().size() != KeyPairEd25519::getPublicKeySize()) { addError(new Error(function_name, "invalid size of sender pubkey")); return TRANSCATION_VALID_INVALID_PUBKEY; } return TRANSACTION_VALID_OK; + } + + std::string TransactionTransfer::getTargetGroupAlias() + { + Poco::ScopedLock _lock(mWorkMutex); + if (mProtoTransfer.has_local()) { + return ""; + } + else if (mProtoTransfer.has_inbound()) { + auto inbound_transfer = mProtoTransfer.inbound(); + return inbound_transfer.other_group(); + } + else if (mProtoTransfer.has_outbound()) { + auto outbound_transfer = mProtoTransfer.outbound(); + return outbound_transfer.other_group(); + } + } + + Poco::AutoPtr TransactionTransfer::createOutbound(const std::string& memo) + { + const char* function_name = "TransactionTransfer::createOutbound"; + auto mm = MemoryManager::getInstance(); + if (!mProtoTransfer.has_inbound()) { + return nullptr; + } + // Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo + //Transaction::createTransfer() + auto inbound = mProtoTransfer.inbound(); + auto sender = controller::User::create(); + if (1 != sender->load((const unsigned char*)inbound.sender().pubkey().data())) { + return nullptr; + } + auto receiver_pubkey = mm->getFreeMemory(inbound.receiver().size()); + memcpy(*receiver_pubkey, inbound.receiver().data(), inbound.receiver().size()); + auto groups = controller::Group::load(inbound.other_group()); + if (1 != groups.size()) { + return nullptr; + } + auto transaction = Transaction::createTransfer(sender, receiver_pubkey, groups[0], inbound.sender().amount(), memo, false); + mm->releaseMemory(receiver_pubkey); + return transaction[0]; } diff --git a/src/cpp/model/gradido/TransactionTransfer.h b/src/cpp/model/gradido/TransactionTransfer.h index 14d1e01b9..558c8a7db 100644 --- a/src/cpp/model/gradido/TransactionTransfer.h +++ b/src/cpp/model/gradido/TransactionTransfer.h @@ -12,6 +12,7 @@ #pragma warning(disable:4800) #include "TransactionBase.h" +//#include "Transaction.h" #include "../proto/gradido/GradidoTransfer.pb.h" #include "../controller/User.h" @@ -19,6 +20,8 @@ namespace model { namespace gradido { + class Transaction; + class TransactionTransfer : public TransactionBase { public: @@ -32,11 +35,18 @@ namespace model { const std::string& getKontoNameCell(int index); const std::string& getAmountCell(int index); + std::string getTargetGroupAlias(); + bool isInbound() { return mProtoTransfer.has_inbound(); } + Poco::AutoPtr createOutbound(const std::string& memo); + void transactionAccepted(Poco::AutoPtr user); protected: const static std::string mInvalidIndexMessage; + int prepare(proto::gradido::TransferAmount* sender, std::string* receiver_pubkey); + TransactionValidation validate(proto::gradido::TransferAmount* sender, std::string* receiver_pubkey); + struct KontoTableEntry { public: diff --git a/src/cpp/model/table/PendingTask.cpp b/src/cpp/model/table/PendingTask.cpp index 5bee7339a..b33f2683a 100644 --- a/src/cpp/model/table/PendingTask.cpp +++ b/src/cpp/model/table/PendingTask.cpp @@ -142,9 +142,11 @@ namespace model select << "SELECT id FROM " << getTableName() << " WHERE user_id = ? " + << " AND hedera_id = ? " + << " AND request = ?" << " AND TIMESTAMPDIFF(SECOND, created, ?) = 0 " << " AND task_type_id = ? " - , into(mID), use(mUserId), use(mCreated), use(mTaskTypeId); + , into(mID), use(mUserId), use(mHederaId), use(mRequest), use(mCreated), use(mTaskTypeId); return select; } diff --git a/src/cpsp/checkTransaction.cpsp b/src/cpsp/checkTransaction.cpsp index fd0d5fecc..ed22883bd 100644 --- a/src/cpsp/checkTransaction.cpsp +++ b/src/cpsp/checkTransaction.cpsp @@ -339,6 +339,9 @@ enum PageState {
    <% } %> <%= transferTransaction->getKontoNameCell(i) %> + <% if(((i+1) % 2) == 0 && transferTransaction->getTargetGroupAlias() != "") { %> + (<%= transferTransaction->getTargetGroupAlias() %>) + <% } %> <%= transferTransaction->getAmountCell(i) %>
    <% } %> diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index 3c73650bd..9fce06102 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -41,7 +41,7 @@ if(!form.empty()) { caller_uri = form.get("caller_uri", ""); - printf("form.get: caller_uri: %s\n", caller_uri.data()); + //printf("form.get: caller_uri: %s\n", caller_uri.data()); bool langUpdatedByBtn = false; auto langBtn = form.get("lang", ""); @@ -93,11 +93,11 @@ langCatalog = mSession->getLanguageCatalog(); */ - if(mSession) { + /*if(mSession) { printf("start with session: %d\n", mSession->getHandle()); } else { printf("start without session\n"); - } + }*/ if(!mSession) { mSession = sm->getNewSession(); @@ -124,7 +124,7 @@ } } - printf("after session: caller_uri: %s\n", caller_uri.data()); + //printf("after session: caller_uri: %s\n", caller_uri.data()); if(email != "" && password != "") { From 53e8249d4dc75656cfd836fdb236f463587b3147 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Mon, 1 Feb 2021 18:05:40 +0100 Subject: [PATCH 173/195] link poco dynamic --- conanfile.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/conanfile.txt b/conanfile.txt index 703260a39..bececd85e 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -6,3 +6,13 @@ gtest/1.8.1@bincrafters/stable [generators] cmake + +[options] +Poco:shared=True +Poco:enable_data_sqlite=False +Poco:enable_mongodb=False +Poco:enable_redis=False +boost:shared=True + +[generators] +virtualrunenv From 1c01594ef54d518770e09a7ba4ed80411cfbd6cd Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 2 Feb 2021 12:25:40 +0100 Subject: [PATCH 174/195] make better visible if timer work --- src/cpp/controller/PendingTask.cpp | 4 +++- src/cpp/model/gradido/Transaction.cpp | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpp/controller/PendingTask.cpp b/src/cpp/controller/PendingTask.cpp index 0605bb755..e36fdcc7d 100644 --- a/src/cpp/controller/PendingTask.cpp +++ b/src/cpp/controller/PendingTask.cpp @@ -145,7 +145,9 @@ namespace controller { } void PendingTask::calledFromTimer(Poco::Timer& timer) { - printf("[PendingTask::calledFromTimer]\n"); + Poco::DateTime now; + std::string now_string = Poco::DateTimeFormatter::format(now, "%f.%m.%Y %H:%M:%S"); + printf("[PendingTask::calledFromTimer] now: %s\n", now_string.data()); Poco::ScopedLock _lock(mWorkMutex); auto result = run(); printf("run result: %d\n", result); diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index 3e5dad767..fae357e04 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -581,6 +581,9 @@ namespace model { // TODO: later check, but now I haven't any way to communicate with the gradido node mTransactionBody->getTransactionBase()->transactionAccepted(getUser()); // trigger community server update in 5 seconds + Poco::DateTime now; + std::string now_string = Poco::DateTimeFormatter::format(now, "%f.%m.%Y %H:%M:%S"); + printf("[%s] trigger community server update in 5 second, now: %s\n", function_name, now_string.data()); CronManager::getInstance()->scheduleUpdateRun(Poco::Timespan(5000, 0)); return 1; } From 89f424f707b0bb9d24a77ed2f08e97473a0e9756 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Feb 2021 13:23:28 +0100 Subject: [PATCH 175/195] Fix bug in CronManager, now the duration are like they should and removed some debug printf --- src/cpp/SingletonManager/CronManager.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/cpp/SingletonManager/CronManager.cpp b/src/cpp/SingletonManager/CronManager.cpp index 73454961e..736cf790b 100644 --- a/src/cpp/SingletonManager/CronManager.cpp +++ b/src/cpp/SingletonManager/CronManager.cpp @@ -68,14 +68,17 @@ void CronManager::runUpdateStep(Poco::Timer& timer) mTimestampsMutex.lock(); //printf("update timestamp sizes: %d\n", mUpdateTimestamps.size()); if (mUpdateTimestamps.size() > 0) { - while (mUpdateTimestamps.size() > 0 && mUpdateTimestamps.front() < Poco::Timestamp()) { + Poco::Timestamp now; + // update maximal once per second + now += Poco::Timespan(1, 0); + while (mUpdateTimestamps.size() > 0 && mUpdateTimestamps.front() < now) { // printf("remove update time in past: %d\n", mUpdateTimestamps.front().epochTime()); mUpdateTimestamps.pop_front(); } - Poco::Timespan next_run = mUpdateTimestamps.front() - Poco::Timestamp(); + Poco::Timespan next_run = mUpdateTimestamps.front() - now; //printf("timer restart called with: %d\n", next_run.seconds()); - mMainTimer.setPeriodicInterval(next_run.milliseconds()); - //mMainTimer.restart(next_run.milliseconds()); + //mMainTimer.setPeriodicInterval(next_run.totalMilliseconds()); + mMainTimer.restart(next_run.totalMilliseconds()); mUpdateTimestamps.pop_front(); } else { @@ -103,10 +106,14 @@ void CronManager::scheduleUpdateRun(Poco::Timespan timespanInFuture) //printf("[CronManager::scheduleUpdateRun] front timestamp and back timestamp:\n%d\n%d\n", frontTimestamp.epochTime(), backTimestamp.epochTime()); //printf("current: \n%d\n", Poco::Timestamp().epochTime()); Poco::Timespan next_run = mUpdateTimestamps.front() - Poco::Timestamp(); - //printf("next run:\n%d\n", next_run.seconds()); + + Poco::DateTime now; + std::string now_string = Poco::DateTimeFormatter::format(now, "%d.%m.%y %H:%M:%S.%i"); + //printf("%s [CronManager::scheduleUpdateRun] next run in %d seconds, %d millis (intervall: %d, default: %d)\n", + //now_string.data(), next_run.seconds(), next_run.milliseconds(), mMainTimer.getPeriodicInterval(), mDefaultIntervalMilliseconds); if (next_run.seconds() > 0 && mMainTimer.getPeriodicInterval() == mDefaultIntervalMilliseconds) { - if (mMainWorkMutex.tryLock()) { - mMainTimer.restart(next_run.milliseconds()); + if (mMainWorkMutex.tryLock(100)) { + mMainTimer.restart(next_run.totalMilliseconds()); mUpdateTimestamps.pop_front(); mMainWorkMutex.unlock(); } @@ -179,7 +186,7 @@ int PingServerTask::run() auto current = Poco::DateTime(); if (model::table::NODE_SERVER_GRADIDO_COMMUNITY == mNodeServer->getModel()->getNodeServerType()) { std::string url_port = mNodeServer->getModel()->getUrlWithPort(); - //printf("%s [PingServerTask::run] call update for %s\n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data(), url_port.data()); + printf("%s [PingServerTask::run] call update for %s\n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data(), url_port.data()); auto json_request = mNodeServer->createJsonRequest(); json_request.request("updateReadNode"); From 191222872df5c7354f3d200bea7948b4befd7925 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Feb 2021 13:24:44 +0100 Subject: [PATCH 176/195] updates to maybe prevent dead lock and warning --- src/cpp/model/gradido/TransactionTransfer.cpp | 1 + src/cpp/model/table/ModelBase.h | 5 +++-- src/cpp/model/table/PendingTask.cpp | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cpp/model/gradido/TransactionTransfer.cpp b/src/cpp/model/gradido/TransactionTransfer.cpp index 26442a4a1..6dfff3c6e 100644 --- a/src/cpp/model/gradido/TransactionTransfer.cpp +++ b/src/cpp/model/gradido/TransactionTransfer.cpp @@ -197,6 +197,7 @@ namespace model { auto outbound_transfer = mProtoTransfer.outbound(); return outbound_transfer.other_group(); } + return ""; } Poco::AutoPtr TransactionTransfer::createOutbound(const std::string& memo) diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index d9087dcbd..2c62d6528 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -35,6 +35,7 @@ namespace model { virtual ~ModelBase(); virtual const char* getTableName() const = 0; + //! called from within of some catch to give more information for debugging, don't lock mutex! virtual std::string toString() = 0; template @@ -122,9 +123,9 @@ namespace model { auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); Poco::Data::Statement select(session); size_t count = 0; - select + select << "SELECT count(id) from " << getTableName() - << " where " << fieldName << " LIKE ? group by group_id" + << " where " << fieldName << " LIKE ? group by " << fieldName ,Poco::Data::Keywords::into(count) ,Poco::Data::Keywords::useRef(fieldValue); diff --git a/src/cpp/model/table/PendingTask.cpp b/src/cpp/model/table/PendingTask.cpp index b33f2683a..bce0bb7f6 100644 --- a/src/cpp/model/table/PendingTask.cpp +++ b/src/cpp/model/table/PendingTask.cpp @@ -69,7 +69,9 @@ namespace model ss << "id: " << mID << std::endl; ss << "user_id: " << mUserId << std::endl; ss << "created: " << Poco::DateTimeFormatter::format(mCreated, "%f.%m.%Y %H:%M:%S") << std::endl; - ss << "task type: " << typeToString((TaskType)mTaskTypeId); + ss << "task type: " << typeToString((TaskType)mTaskTypeId) << std::endl; + ss << "child pending task id: " << std::to_string(mChildPendingTaskId) << std::endl; + ss << "parent pending task id: " << std::to_string(mParentPendingTaskId) << std::endl; return ss.str(); } @@ -138,7 +140,6 @@ namespace model Poco::Data::Statement PendingTask::_loadIdFromDB(Poco::Data::Session session) { Poco::Data::Statement select(session); - Poco::ScopedLock _lock(mWorkMutex); select << "SELECT id FROM " << getTableName() << " WHERE user_id = ? " @@ -155,7 +156,6 @@ namespace model Poco::Data::Statement PendingTask::_insertIntoDB(Poco::Data::Session session) { Poco::Data::Statement insert(session); - Poco::ScopedLock _lock(mWorkMutex); insert << "INSERT INTO " << getTableName() << " (user_id, hedera_id, request, created, task_type_id, child_pending_task_id, parent_pending_task_id) VALUES(?,?,?,?,?,?,?)" From ecf2a3a407bd97749c0f5b36d67f985814fa7b6f Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Feb 2021 13:26:01 +0100 Subject: [PATCH 177/195] remove debug printf and add transaction type to string function for both hedera and gradido transactions --- src/cpp/model/gradido/Transaction.cpp | 16 +++++++++------- src/cpp/model/gradido/TransactionBody.cpp | 12 ++++++++++++ src/cpp/model/gradido/TransactionBody.h | 1 + src/cpp/model/hedera/TransactionBody.cpp | 13 ++++++++++++- src/cpp/model/hedera/TransactionBody.h | 1 + 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index fae357e04..2207da9e7 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -304,7 +304,7 @@ namespace model { auto sigBytes = sigPair->mutable_ed25519(); *sigBytes = std::string((char*)*sign, crypto_sign_BYTES); auto sign_hex_string = DataTypeConverter::binToHex(sign); - printf("sign hex: %s\n", sign_hex_string.data()); + //printf("sign hex: %s\n", sign_hex_string.data()); mm->releaseMemory(sign); updateRequestInDB(); @@ -323,7 +323,7 @@ namespace model { } //getModel()->updateIntoDB("request", ) - printf("[Transaction::sign] reference-count: %d\n", mReferenceCount); + //printf("[Transaction::sign] reference-count: %d\n", mReferenceCount); return true; } @@ -570,8 +570,10 @@ namespace model { auto hedera_precheck_code_string = hedera_transaction_response->getPrecheckCodeString(); auto precheck_code = hedera_transaction_response->getPrecheckCode(); auto cost = hedera_transaction_response->getCost(); - - printf("hedera response: %s, cost: %" PRIu64 "\n", hedera_precheck_code_string.data(), cost); + + printf("hedera response: %s, cost: %" PRIu64 ", type: %s\n", + hedera_precheck_code_string.data(), cost, + TransactionBody::transactionTypeToString(mTransactionBody->getType())); if (precheck_code == proto::INVALID_TRANSACTION_START) { int zahl = 0; return -5; @@ -583,8 +585,8 @@ namespace model { // trigger community server update in 5 seconds Poco::DateTime now; std::string now_string = Poco::DateTimeFormatter::format(now, "%f.%m.%Y %H:%M:%S"); - printf("[%s] trigger community server update in 5 second, now: %s\n", function_name, now_string.data()); - CronManager::getInstance()->scheduleUpdateRun(Poco::Timespan(5000, 0)); + //printf("[%s] trigger community server update in 5 second, now: %s\n", function_name, now_string.data()); + CronManager::getInstance()->scheduleUpdateRun(Poco::Timespan(5, 0)); return 1; } @@ -686,7 +688,7 @@ namespace model { return 0; }*/ result = mTransaction->runSendTransaction(); - printf("[SendTransactionTask::run] result: %d\n", result); + //printf("[SendTransactionTask::run] result: %d\n", result); // delete because of error if (-1 == result) { mTransaction->deleteFromDB(); diff --git a/src/cpp/model/gradido/TransactionBody.cpp b/src/cpp/model/gradido/TransactionBody.cpp index a59634b4d..3859ef969 100644 --- a/src/cpp/model/gradido/TransactionBody.cpp +++ b/src/cpp/model/gradido/TransactionBody.cpp @@ -172,6 +172,18 @@ namespace model { return ""; } + const char* TransactionBody::transactionTypeToString(TransactionType type) + { + switch (type) + { + case model::gradido::TRANSACTION_NONE: return "NONE"; + case model::gradido::TRANSACTION_CREATION: return "Creation"; + case model::gradido::TRANSACTION_TRANSFER: return "Transfer"; + case model::gradido::TRANSACTION_GROUP_MEMBER_UPDATE: return "Group Member Update"; + } + return ""; + } + TransactionCreation* TransactionBody::getCreationTransaction() diff --git a/src/cpp/model/gradido/TransactionBody.h b/src/cpp/model/gradido/TransactionBody.h index 784644ee5..9d026ecf9 100644 --- a/src/cpp/model/gradido/TransactionBody.h +++ b/src/cpp/model/gradido/TransactionBody.h @@ -41,6 +41,7 @@ namespace model { static Poco::AutoPtr load(const std::string& protoMessageBin); inline TransactionType getType() { Poco::ScopedLock _lock(mWorkMutex); return mType; } + static const char* transactionTypeToString(TransactionType type); std::string getMemo(); void setMemo(const std::string& memo); diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index c50567a1e..291dd5542 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -113,6 +113,17 @@ namespace model { return false; } + const char* TransactionBody::TransactionBodyTypeToString(TransactionBodyType type) + { + switch (type) { + case TRANSACTION_CONSENSUS_CREATE_TOPIC: return "Consensus Create Topic"; + case TRANSACTION_CONSENSUS_SUBMIT_MESSAGE: return "Consensus Submit Message"; + case TRANSACTION_CRYPTO_CREATE: return "Crypto Create"; + case TRANSACTION_CRYPTO_TRANSFER: return "Crypto Transfer"; + } + return ""; + } + void TransactionBody::setMemo(const std::string& memo) { mTransactionBody.set_memo(memo); @@ -136,7 +147,7 @@ namespace model { timestamp->set_nanos(microseconds * 1000); // make sure timestamp is some nanos old //timestamp->set_nanos(microseconds * 900); - printf("hedera transaction body timestamp: %d.%d\n", timestamp->seconds(), timestamp->nanos()); + // printf("hedera transaction body timestamp: %d.%d\n", timestamp->seconds(), timestamp->nanos()); } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index 7697434ec..b9c25d0c4 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -50,6 +50,7 @@ namespace model { inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } inline controller::NodeServerConnection getConnection() const { return mConnection; } inline TransactionBodyType getType() const { return mType; } + static const char* TransactionBodyTypeToString(TransactionBodyType type); void updateTimestamp(); protected: From 03f619fac1dbf6310c5f98dd0f2b50c56dad8e13 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Feb 2021 13:26:32 +0100 Subject: [PATCH 178/195] wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time --- .../HTTPInterface/AdminNodeServerTestPage.cpp | 37 ++++++++++--------- src/cpsp/adminNodeServerTest.cpsp | 3 ++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp index 322fcf637..b9bfa69b4 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp @@ -506,31 +506,34 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques } else { auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(hedera_timeout * 100); + transaction4[0]->sign(user_2); auto transaction4_json = transaction4[0]->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 243 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction4_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t\n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    6. Wait "; -#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( hedera_timeout ); responseStream << " seconds to give hedera time to process transactions

    \n"; responseStream << "\t\t\t"; -#line 249 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(!steps[4]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { Poco::Thread::sleep(hedera_timeout * 1000); } responseStream << "\n"; @@ -538,12 +541,12 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    7. Ask choosen node for transaction and print result

    \n"; responseStream << "\t\t\t"; -#line 257 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 260 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[5] || node_server.isNull()) { responseStream << "

    skipped

    \n"; responseStream << "\t\t\t"; -#line 260 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 263 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto node_server_model = node_server->getModel(); JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); @@ -556,20 +559,20 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 271 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 271 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { Profiler time3; auto node_server_model = node_server->getModel(); @@ -584,23 +587,23 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t"; -#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t

Time: "; -#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 296 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time3.string() ); responseStream << "

\n"; responseStream << "\t"; -#line 294 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\n"; responseStream << "
\n"; responseStream << "\n"; // begin include footer.cpsp diff --git a/src/cpsp/adminNodeServerTest.cpsp b/src/cpsp/adminNodeServerTest.cpsp index b9fe4f829..f504caa0d 100644 --- a/src/cpsp/adminNodeServerTest.cpsp +++ b/src/cpsp/adminNodeServerTest.cpsp @@ -238,6 +238,9 @@ enum PageType <% } else { auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(hedera_timeout * 100); + transaction4[0]->sign(user_2); auto transaction4_json = transaction4[0]->getTransactionAsJson(true); %>

<%= DataTypeConverter::replaceNewLineWithBr(transaction4_json) %>

From ae096e2d2e34f6083af712de8e3ccaf4a21d98b1 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Fri, 5 Feb 2021 12:15:57 +0100 Subject: [PATCH 179/195] check if update timestamps list is empty after removing all outdated entrys --- src/cpp/SingletonManager/CronManager.cpp | 33 ++++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/cpp/SingletonManager/CronManager.cpp b/src/cpp/SingletonManager/CronManager.cpp index 736cf790b..f3eae73a6 100644 --- a/src/cpp/SingletonManager/CronManager.cpp +++ b/src/cpp/SingletonManager/CronManager.cpp @@ -67,7 +67,10 @@ void CronManager::runUpdateStep(Poco::Timer& timer) mTimestampsMutex.lock(); //printf("update timestamp sizes: %d\n", mUpdateTimestamps.size()); - if (mUpdateTimestamps.size() > 0) { + bool timerRestarted = false; + + if (mUpdateTimestamps.size() > 0) + { Poco::Timestamp now; // update maximal once per second now += Poco::Timespan(1, 0); @@ -75,19 +78,21 @@ void CronManager::runUpdateStep(Poco::Timer& timer) // printf("remove update time in past: %d\n", mUpdateTimestamps.front().epochTime()); mUpdateTimestamps.pop_front(); } - Poco::Timespan next_run = mUpdateTimestamps.front() - now; - //printf("timer restart called with: %d\n", next_run.seconds()); - //mMainTimer.setPeriodicInterval(next_run.totalMilliseconds()); - mMainTimer.restart(next_run.totalMilliseconds()); - mUpdateTimestamps.pop_front(); - } - else { - if (mMainTimer.getPeriodicInterval() != mDefaultIntervalMilliseconds) { - //printf("reset to default interval\n"); - mMainTimer.setPeriodicInterval(mDefaultIntervalMilliseconds); - //mMainTimer.restart(mDefaultIntervalMilliseconds); + if (mUpdateTimestamps.size() > 0) { + Poco::Timespan next_run = mUpdateTimestamps.front() - now; + //printf("timer restart called with: %d\n", next_run.seconds()); + //mMainTimer.setPeriodicInterval(next_run.totalMilliseconds()); + mMainTimer.restart(next_run.totalMilliseconds()); + mUpdateTimestamps.pop_front(); + timerRestarted = true; } } + + if (!timerRestarted && mMainTimer.getPeriodicInterval() != mDefaultIntervalMilliseconds) { + //printf("reset to default interval\n"); + mMainTimer.setPeriodicInterval(mDefaultIntervalMilliseconds); + //mMainTimer.restart(mDefaultIntervalMilliseconds); + } mTimestampsMutex.unlock(); //printf("[CronManager::runUpdateStep] end\n"); } @@ -188,8 +193,8 @@ int PingServerTask::run() std::string url_port = mNodeServer->getModel()->getUrlWithPort(); printf("%s [PingServerTask::run] call update for %s\n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data(), url_port.data()); - auto json_request = mNodeServer->createJsonRequest(); - json_request.request("updateReadNode"); + //auto json_request = mNodeServer->createJsonRequest(); + //json_request.request("updateReadNode"); } return 0; } \ No newline at end of file From 95cb35129b49508cba672d5aef13742f5d4a3d55 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Fri, 5 Feb 2021 12:16:58 +0100 Subject: [PATCH 180/195] adjust for cross group transaction test and also fix false order for real version --- .../HTTPInterface/AdminNodeServerTestPage.cpp | 493 +++++++++++++----- src/cpp/lib/DataTypeConverter.cpp | 7 + src/cpp/lib/DataTypeConverter.h | 1 + src/cpp/model/gradido/Transaction.cpp | 119 ++++- src/cpp/model/gradido/Transaction.h | 3 + src/cpp/model/gradido/TransactionBody.cpp | 91 +++- src/cpp/model/gradido/TransactionBody.h | 2 + src/cpp/model/gradido/TransactionTransfer.cpp | 57 +- src/cpp/model/gradido/TransactionTransfer.h | 14 + src/cpsp/adminNodeServerTest.cpsp | 198 +++++-- 10 files changed, 783 insertions(+), 202 deletions(-) diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp index b9bfa69b4..a406800f5 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp @@ -45,11 +45,14 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques const char* pageName = "Node Server Test"; PageType page = PAGE_CHOOSE_TEST; Poco::AutoPtr node_server; + Poco::AutoPtr node_server2; Poco::AutoPtr user; Poco::AutoPtr hedera_topic; - int hedera_timeout = 9; + Poco::AutoPtr hedera_topic2; + int hedera_timeout = 4; + int sleep_ms_between_transactions = 1000; - bool steps[6]; memset(steps, 1, 6 * sizeof(bool)); + bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); if(!form.empty()) @@ -61,6 +64,13 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques node_server = controller::NodeServer::load(node_server_id); } } + node_server_id_string = form.get("test-node-servers2", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server2 = controller::NodeServer::load(node_server_id); + } + } auto topic_id_string = form.get("test-hedera-topic", ""); if(topic_id_string != "") { int topic_id = 0; @@ -68,18 +78,25 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques hedera_topic = controller::HederaTopic::load(topic_id); } } + topic_id_string = form.get("test-hedera-topic2", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic2 = controller::HederaTopic::load(topic_id); + } + } auto test_timeout_string = form.get("test-timeout", ""); if(test_timeout_string != "") { DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); } auto submit = form.get("submit", ""); - if(submit == "Run 4-Test") { + if(submit == "Run 6-Test") { page = PAGE_RUN_4_SET_TEST; } else if(submit == "json-rpc getTransactions") { page = PAGE_GET_TRANSACTION_RPC_CALL; } std::string step_temp; - for(int i = 0; i < 6; i++) { + for(int i = 0; i < 8; i++) { std::string name = "step-"; name += std::to_string(i+2); step_temp = form.get(name, ""); @@ -162,206 +179,302 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 82 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 99 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; responseStream << "\t\n"; responseStream << "\t
\n"; responseStream << "\t \n"; +#line 103 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\" onclick=\"openTab(event, 'test-4')\">Test 6-Set (3 AddMember, Creation, 2 Transfer)\n"; responseStream << "\t \n"; responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; - responseStream << "\t\t\t

Test 4-Set (2 AddMember, Creation, Transfer)\n"; + responseStream << "\t\t\t

Test 6-Set (3 AddMember, Creation, 2 Transfer)\n"; responseStream << "\t\t

\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t

1. Create two new accounts and show user public keys for comparisation

\n"; + responseStream << "\t\t\t\t

1. Create three new accounts and show user public keys for comparisation

\n"; responseStream << "\t\t\t\t

2. Send a add-member transaction to hedera topic with one signature (first user)

\n"; responseStream << "\t\t\t\t

3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

\n"; responseStream << "\t\t\t\t

4. Send a creation transaction to second user, signed by first user

\n"; responseStream << "\t\t\t\t

5. Send a transfer transaction from second user to first user signed by second user

\n"; responseStream << "\t\t\t\t

6. Wait x seconds to give hedera time to process transactions

\n"; +#line 117 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " name=\"step-6\" value=\"1\"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)

\n"; responseStream << "\t\t\t\t

7. Ask choosen node for transaction and print result

\n"; - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t"; -#line 104 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 118 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " name=\"step-7\" value=\"1\"/> 7. Send a cross group transfer from second user to third user signed by second user

\n"; + responseStream << "\t\t\t\t

8. Wait x seconds to give hedera time to process transactions

\n"; + responseStream << "\t\t\t\t

9. Ask choosen node for transaction and print result

\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tGroup 1 \n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 124 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(node_servers.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\tEdit Node-Servers\n"; - responseStream << "\t\t\t\t"; -#line 106 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 128 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" for(auto it = node_servers.begin(); it != node_servers.end(); it++) { - auto model = (*it)->getModel(); - responseStream << "\n"; - responseStream << "\t\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 112 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t\t\t"; +#line 132 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t"; -#line 115 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 135 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(hedera_topics.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\tEdit Hedera-Topics\n"; - responseStream << "\t\t\t\t"; -#line 117 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) { - auto model = (*it)->getModel(); - auto hedera_account = (*it)->getAutoRenewAccount(); - if(hedera_account->getModel()->getNetworkType() != ServerConfig::HEDERA_TESTNET) { - continue; - } - responseStream << "\n"; - responseStream << "\t\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 127 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t\t\t"; +#line 147 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tGroup 2 \n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 153 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(node_servers.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Node-Servers\n"; + responseStream << "\t\t\t\t\t"; +#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(hedera_topics.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Hedera-Topics\n"; + responseStream << "\t\t\t\t\t"; +#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t seconds \n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t

Test 4-Set (2 AddMember, Creation, Transfer)\n"; responseStream << "\t\t

\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t"; -#line 142 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(node_servers.size() == 0) { responseStream << "\n"; responseStream << "\t\t\t\t\tEdit Node-Servers\n"; responseStream << "\t\t\t\t"; -#line 144 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; @@ -369,17 +482,19 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
\n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    1. Create two new accounts and show user public keys for comparisation:

    \n"; + responseStream << "\t\t\t

    1. Create three new accounts and show user public keys for comparisation:

    \n"; responseStream << "\t\t\t"; -#line 160 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 211 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" Profiler time2; auto group_id = hedera_topic->getModel()->getGroupId(); + auto group_id2 = hedera_topic2->getModel()->getGroupId(); auto user_group = controller::Group::load(group_id); + auto user_group2 = controller::Group::load(group_id2); auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; @@ -395,30 +510,51 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); user_2->setGradidoKeyPair(gradido_key_pair_2); user_2->login(password2); + + std::string password3 = "jaue_skaiellasealaK"; + auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); + auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); + user_3->setGradidoKeyPair(gradido_key_pair_3); + user_3->login(password3); responseStream << "\t\t\t\n"; - responseStream << "\t\t\t

    User 1: "; -#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t

    "; +#line 240 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_group->getModel()->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t

    User 1: "; +#line 241 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( user_1->getPublicHex() ); responseStream << "

    \n"; - responseStream << "\t\t\t

    User 2: "; -#line 181 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t

    User 2: "; +#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( user_2->getPublicHex() ); responseStream << "

    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t
    "; +#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_group2->getModel()->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t

    User 3: "; +#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_3->getPublicHex() ); + responseStream << "

    \n"; + responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t

    Time: "; -#line 182 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "\n"; responseStream << "\t\t

  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    2. Send a add-member transaction to hedera topic with one signature (first user)

    \n"; responseStream << "\t\t\t"; -#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[0]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 190 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 255 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); @@ -426,127 +562,202 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques auto transaction1_json = transaction1->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 196 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 261 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction1_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 197 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 262 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 263 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "\n"; responseStream << "\t\t

  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

    \n"; responseStream << "\t\t\t"; -#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[1]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 271 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); transaction2->sign(user_2); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction2->sign(user_1); auto transaction2_json = transaction2->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction2_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 282 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "\n"; responseStream << "\t\t

  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    4. Send a creation transaction to second user, signed by first user

    \n"; responseStream << "\t\t\t"; -#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[2]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction3->sign(user_1); auto transaction3_json = transaction3->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 228 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction3_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 229 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 298 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 230 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 299 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    5. Send a transfer transaction from second user to first user signed by second user

    \n"; responseStream << "\t\t\t"; -#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 303 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[3]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 307 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(hedera_timeout * 100); + Poco::Thread::sleep(sleep_ms_between_transactions); transaction4[0]->sign(user_2); auto transaction4_json = transaction4[0]->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 315 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction4_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 316 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 317 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    6. Wait "; -#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    \n"; + responseStream << "\t\t\t"; +#line 321 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[4]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 325 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); + transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction5->sign(user_3); + auto transaction5_json = transaction5->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 332 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction5_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 333 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 334 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    7. Send a cross group transfer from second user to third user signed by second user

    \n"; + responseStream << "\t\t\t"; +#line 338 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[5]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 342 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); + auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); + if(!transaction6.size()) { + responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\treport_problem\n"; + responseStream << "\t\t\t\t\tError creating Transaction\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t"; +#line 351 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } else { + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction6[0]->sign(user_2); + auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t\t\t

    "; +#line 357 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_json) ); + responseStream << "

    \t\t\n"; + responseStream << "\t\t\t\t"; +#line 358 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t"; +#line 359 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " \n"; + responseStream << "\t\t\t

    Time: "; +#line 360 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    8. Wait "; +#line 363 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( hedera_timeout ); responseStream << " seconds to give hedera time to process transactions

    \n"; responseStream << "\t\t\t"; -#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(!steps[4]) { responseStream << "\n"; +#line 364 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(!steps[6]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 366 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { Poco::Thread::sleep(hedera_timeout * 1000); } responseStream << "\n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    7. Ask choosen node for transaction and print result

    \n"; + responseStream << "\t\t\t

    9. Ask choosen node for transaction and print result

    \n"; responseStream << "\t\t\t"; -#line 260 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 372 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); - if(!steps[5] || node_server.isNull()) { + if(!steps[7] || node_server.isNull()) { responseStream << "

    skipped

    \n"; responseStream << "\t\t\t"; -#line 263 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 375 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto node_server_model = node_server->getModel(); JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); @@ -559,20 +770,20 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 389 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 392 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { Profiler time3; auto node_server_model = node_server->getModel(); @@ -587,23 +798,23 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t"; -#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 405 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 405 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t

Time: "; -#line 296 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 408 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time3.string() ); responseStream << "

\n"; responseStream << "\t"; -#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 409 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\n"; responseStream << "
\n"; responseStream << "\n"; // begin include footer.cpsp diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index eed9967a8..62417f638 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -304,6 +304,13 @@ namespace DataTypeConverter return microseconds; } + Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp) + { + // microseconds + google::protobuf::int64 microseconds = timestamp.seconds() * (google::protobuf::int64)10e5 + (google::protobuf::int64)(timestamp.nanos()) / (google::protobuf::int64)10e2; + return microseconds; + } + void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp) { auto microsecondsTotal = pocoTimestamp.epochMicroseconds(); diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index e4a0487fe..38249f740 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -56,6 +56,7 @@ namespace DataTypeConverter { std::string convertTimespanToLocalizedString(Poco::Timespan duration, LanguageCatalog* lang); Poco::Timestamp convertFromProtoTimestamp(const proto::Timestamp& timestamp); + Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp); void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp); void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::gradido::Timestamp* protoTimestamp); Poco::Timestamp convertFromProtoTimestampSeconds(const proto::gradido::TimestampSeconds& timestampSeconds); diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index 2207da9e7..70fc217cb 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -136,17 +136,24 @@ namespace model { else { auto sender_group = controller::Group::load(sender_model->getGroupId()); + if (sender_group.isNull()) + { + em->addError(new ParamError(function_name, "couldn't find group with id: ", sender_model->getGroupId())); + em->sendErrorsAsEmail(); + return results; + } Poco::AutoPtr transaction_group; Poco::AutoPtr topic_group; // default constructor set it to now Poco::Timestamp pairedTransactionId; // create only inbound transaction, and outbound before sending to hedera //for (int i = 0; i < 1; i++) { - if (inbound) { + if (!inbound) { transaction_group = receiverGroup; topic_group = sender_group; } - else if(!inbound) { + // transaction send to receiver blockchain + else if(inbound) { transaction_group = sender_group; topic_group = receiverGroup; } @@ -166,20 +173,107 @@ namespace model { auto body = TransactionBody::create(memo, sender, receiverPubkey, amount, pairedTransactionId, transaction_group); Poco::AutoPtr transaction = new Transaction(body); transaction->getModel()->setHederaId(topic_id->getModel()->getID()); + auto transfer_transaction = transaction->getTransactionBody()->getTransferTransaction(); + transfer_transaction->setOwnGroupAlias(sender_group->getModel()->getAlias()); + transfer_transaction->setTargetGroupAlias(receiverGroup->getModel()->getAlias()); + results.push_back(transaction); // } } + for (auto it = results.begin(); it != results.end(); it++) { - (*it)->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER); - PendingTasksManager::getInstance()->addTask(*it); + if (!(*it)->getTransactionBody()->getTransferTransaction()->isInbound()) { + (*it)->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER); + PendingTasksManager::getInstance()->addTask(*it); + } } + return results; } - + bool Transaction::setTopicIdByGroup(const std::string& alias) + { + static const char* function_name = "Transaction::setTopicIdByGroup"; + auto topic_groups = controller::Group::load(alias); + if (topic_groups.size() != 1) { + addError(new ParamError(function_name, "not one group found for alias: ", alias)); + sendErrorsAsEmail(); + return false; + } + auto topic = controller::HederaId::find(topic_groups[0]->getModel()->getID(), ServerConfig::g_HederaNetworkType); + if (topic.isNull()) { + addError(new ParamError(function_name, "no topic found for group id", topic_groups[0]->getModel()->getID())); + addError(new ParamError(function_name, "and network type: ", ServerConfig::g_HederaNetworkType)); + sendErrorsAsEmail(); + return false; + } + getModel()->setHederaId(topic->getModel()->getID()); + return true; + } + + Poco::AutoPtr Transaction::createTransfer(const MemoryBin* senderPubkey, Poco::AutoPtr receiver, std::string senderGroupAlias, Poco::UInt32 amount, const std::string& memo) + { + Poco::AutoPtr result; + auto em = ErrorManager::getInstance(); + static const char* function_name = "Transaction::create transfer 2"; + + if (receiver.isNull() || !receiver->getModel() || !senderPubkey || !amount) { + return result; + } + + //std::vector> bodys; + auto receiver_model = receiver->getModel(); + auto network_type = ServerConfig::g_HederaNetworkType; + + auto sender_groups = controller::Group::load(senderGroupAlias); + if (!sender_groups.size()) { + em->addError(new ParamError(function_name, "couldn't find group", senderGroupAlias)); + em->sendErrorsAsEmail(); + return result; + } + Poco::AutoPtr transaction_group; + Poco::AutoPtr topic_group = controller::Group::load(receiver_model->getGroupId()); + if (topic_group.isNull()) { + em->addError(new ParamError(function_name, "topic group not found", receiver_model->getGroupId())); + em->sendErrorsAsEmail(); + return result; + } + // default constructor set it to now + Poco::Timestamp pairedTransactionId; + // create only inbound transaction, and outbound before sending to hedera + //for (int i = 0; i < 1; i++) { + + //transaction_group = receiverGroup; + //topic_group = sender_group; + + auto topic_id = controller::HederaId::find(topic_group->getModel()->getID(), network_type); + if (topic_id.isNull()) { + em->addError(new ParamError(function_name, "could'n find topic for group: ", receiver_model->getGroupId())); + em->addError(new ParamError(function_name, "network type: ", network_type)); + em->sendErrorsAsEmail(); + return result; + } + if (transaction_group.isNull()) { + em->addError(new Error(function_name, "transaction group is zero, inbound")); + em->sendErrorsAsEmail(); + return result; + } + + auto body = TransactionBody::create(memo, senderPubkey, receiver, amount, pairedTransactionId, transaction_group); + result = new Transaction(body); + result->getModel()->setHederaId(topic_id->getModel()->getID()); + + // } + + //result->insertPendingTaskIntoDB(receiver, model::table::TASK_TYPE_TRANSFER); + //PendingTasksManager::getInstance()->addTask(result); + + return result; + } + Poco::AutoPtr Transaction::load(model::table::PendingTask* dbModel) { @@ -313,9 +407,18 @@ namespace model { { if (getTransactionBody()->isTransfer()) { auto transfer = getTransactionBody()->getTransferTransaction(); - if (transfer->isInbound()) { - auto transaction = transfer->createOutbound(getTransactionBody()->getMemo()); - transaction->sign(user); + if (transfer->isOutbound()) { + auto transaction = transfer->createInbound(getTransactionBody()->getMemo()); + if (!transaction.isNull()) { + transaction->sign(user); + // dirty hack because gn crashes if its get transactions out of order + Poco::Thread::sleep(1000); + } + else { + addError(new Error(function_name, "Error creating outbound transaction")); + return false; + } + } } UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr(this, true))); diff --git a/src/cpp/model/gradido/Transaction.h b/src/cpp/model/gradido/Transaction.h index c135fd89f..c8147a6a1 100644 --- a/src/cpp/model/gradido/Transaction.h +++ b/src/cpp/model/gradido/Transaction.h @@ -31,6 +31,7 @@ namespace model { //! \brief transfer //! \return for cross group transaction return two transactions static std::vector> createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo, bool inbound = true); + Poco::AutoPtr createTransfer(const MemoryBin* senderPubkey, Poco::AutoPtr receiver, std::string senderGroupAlias, Poco::UInt32 amount, const std::string& memo); //! \brief creation transaction static Poco::AutoPtr createCreation(Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate, const std::string& memo); static Poco::AutoPtr load(model::table::PendingTask* dbModel); @@ -60,6 +61,8 @@ namespace model { std::string getTransactionAsJson(bool replaceBase64WithHex = false); + bool setTopicIdByGroup(const std::string& alias); + protected: diff --git a/src/cpp/model/gradido/TransactionBody.cpp b/src/cpp/model/gradido/TransactionBody.cpp index 3859ef969..2e69085e0 100644 --- a/src/cpp/model/gradido/TransactionBody.cpp +++ b/src/cpp/model/gradido/TransactionBody.cpp @@ -61,7 +61,7 @@ namespace model { { auto group_model = group->getModel(); proto::gradido::CrossGroupTransfer* cross_group_transfer = nullptr; - if (group->getModel()->getID() == sender->getModel()->getGroupId()) { + if (group->getModel()->getID() != sender->getModel()->getGroupId()) { cross_group_transfer = gradido_transfer->mutable_outbound(); } else { @@ -84,6 +84,95 @@ namespace model { return obj; } + Poco::AutoPtr TransactionBody::create(const std::string& memo, const MemoryBin* senderPublicKey, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId /*= Poco::Timestamp()*/, Poco::AutoPtr group/* = nullptr*/) + { + if (receiver.isNull() || !receiver->getModel()) { + return nullptr; + } + auto receiver_model = receiver->getModel(); + + + Poco::AutoPtr obj = new TransactionBody; + obj->mTransactionBody.set_memo(memo); + auto gradido_transfer = obj->mTransactionBody.mutable_transfer(); + proto::gradido::TransferAmount* transfer_amount = nullptr; + std::string* sender = nullptr; + + auto group_model = group->getModel(); + proto::gradido::CrossGroupTransfer* cross_group_transfer = nullptr; + + cross_group_transfer = gradido_transfer->mutable_inbound(); + + transfer_amount = cross_group_transfer->mutable_sender(); + sender = transfer_amount->mutable_pubkey(); + auto paired_transaction_id = cross_group_transfer->mutable_paired_transaction_id(); + DataTypeConverter::convertToProtoTimestamp(pairedTransactionId, paired_transaction_id); + cross_group_transfer->set_other_group(group_model->getAlias()); + + transfer_amount->set_amount(amount); + transfer_amount->set_pubkey(senderPublicKey, KeyPairEd25519::getPublicKeySize()); + cross_group_transfer->set_receiver(receiver_model->getPublicKey(), receiver_model->getPublicKeySize()); + *sender = std::string((const char*)senderPublicKey->data(), senderPublicKey->size()); + + obj->mType = TRANSACTION_TRANSFER; + obj->mTransactionSpecific = new TransactionTransfer(memo, obj->mTransactionBody.transfer()); + obj->mTransactionSpecific->prepare(); + + return obj; + } + + Poco::AutoPtr TransactionBody::create(const std::string& memo, const MemoryBin* senderPublicKey, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, const std::string groupAlias, TransactionTransferType transferType, Poco::Timestamp pairedTransactionId/* = Poco::Timestamp()*/) + { + assert(transferType == TRANSFER_CROSS_GROUP_INBOUND || transferType == TRANSFER_CROSS_GROUP_OUTBOUND || transferType == TRANSFER_LOCAL); + if (!senderPublicKey || !receiverPublicKey) { + return nullptr; + } + + Poco::AutoPtr obj = new TransactionBody; + obj->mTransactionBody.set_memo(memo); + auto gradido_transfer = obj->mTransactionBody.mutable_transfer(); + proto::gradido::TransferAmount* transfer_amount = nullptr; + proto::gradido::CrossGroupTransfer* cross_group_transfer = nullptr; + proto::gradido::LocalTransfer* local_transfer = nullptr; + + switch (transferType) + { + case TRANSFER_CROSS_GROUP_INBOUND: + cross_group_transfer = gradido_transfer->mutable_inbound(); + break; + case TRANSFER_CROSS_GROUP_OUTBOUND: + cross_group_transfer = gradido_transfer->mutable_outbound(); + break; + case TRANSFER_LOCAL: + local_transfer = gradido_transfer->mutable_local(); + break; + } + + + if (local_transfer) { + transfer_amount = local_transfer->mutable_sender(); + local_transfer->set_receiver((const char*)receiverPublicKey->data(), receiverPublicKey->size()); + } + else if (cross_group_transfer) { + transfer_amount = cross_group_transfer->mutable_sender(); + auto paired_transaction_id = cross_group_transfer->mutable_paired_transaction_id(); + DataTypeConverter::convertToProtoTimestamp(pairedTransactionId, paired_transaction_id); + cross_group_transfer->set_other_group(groupAlias); + + cross_group_transfer->set_receiver((const char*)receiverPublicKey->data(), receiverPublicKey->size()); + } + + + transfer_amount->set_amount(amount); + transfer_amount->set_pubkey((const unsigned char*)senderPublicKey->data(), senderPublicKey->size()); + + obj->mType = TRANSACTION_TRANSFER; + obj->mTransactionSpecific = new TransactionTransfer(memo, obj->mTransactionBody.transfer()); + obj->mTransactionSpecific->prepare(); + + return obj; + } + Poco::AutoPtr TransactionBody::create(const std::string& memo, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate) { if (receiver.isNull() || !receiver->getModel()) { diff --git a/src/cpp/model/gradido/TransactionBody.h b/src/cpp/model/gradido/TransactionBody.h index 9d026ecf9..f88344eb2 100644 --- a/src/cpp/model/gradido/TransactionBody.h +++ b/src/cpp/model/gradido/TransactionBody.h @@ -34,6 +34,8 @@ namespace model { //! \param group if group.isNull() it is a local transfer, else cross group transfer, //! \param group if group is same as sender group outbound, else inbound static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr sender, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId = Poco::Timestamp(), Poco::AutoPtr group = nullptr); + static Poco::AutoPtr create(const std::string& memo, const MemoryBin* senderPublicKey, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId = Poco::Timestamp(), Poco::AutoPtr group = nullptr); + static Poco::AutoPtr create(const std::string& memo, const MemoryBin* senderPublicKey, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, const std::string groupAlias, TransactionTransferType transferType, Poco::Timestamp pairedTransactionId = Poco::Timestamp()); //! \brief GradidoCreation Transaction static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate); diff --git a/src/cpp/model/gradido/TransactionTransfer.cpp b/src/cpp/model/gradido/TransactionTransfer.cpp index 6dfff3c6e..6e458a87a 100644 --- a/src/cpp/model/gradido/TransactionTransfer.cpp +++ b/src/cpp/model/gradido/TransactionTransfer.cpp @@ -1,5 +1,7 @@ #include "TransactionTransfer.h" #include "Transaction.h" +#include "../../SingletonManager/ErrorManager.h" +#include "../../controller/HederaId.h" namespace model { namespace gradido { @@ -204,26 +206,63 @@ namespace model { { const char* function_name = "TransactionTransfer::createOutbound"; auto mm = MemoryManager::getInstance(); + auto em = ErrorManager::getInstance(); if (!mProtoTransfer.has_inbound()) { return nullptr; } // Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo //Transaction::createTransfer() auto inbound = mProtoTransfer.inbound(); - auto sender = controller::User::create(); - if (1 != sender->load((const unsigned char*)inbound.sender().pubkey().data())) { - return nullptr; - } + + auto sender_pubkey = mm->getFreeMemory(inbound.sender().pubkey().size()); + memcpy(*sender_pubkey, inbound.sender().pubkey().data(), inbound.sender().pubkey().size()); auto receiver_pubkey = mm->getFreeMemory(inbound.receiver().size()); memcpy(*receiver_pubkey, inbound.receiver().data(), inbound.receiver().size()); - auto groups = controller::Group::load(inbound.other_group()); - if (1 != groups.size()) { + + auto body = TransactionBody::create( + memo, sender_pubkey, receiver_pubkey, + inbound.sender().amount(), mTargetGroupAlias, TRANSFER_CROSS_GROUP_OUTBOUND, + DataTypeConverter::convertFromProtoTimestamp(inbound.paired_transaction_id()) + ); + + auto transaction = Poco::AutoPtr(new Transaction(body)); + transaction->setTopicIdByGroup(mOwnGroupAlias); + + mm->releaseMemory(receiver_pubkey); + mm->releaseMemory(sender_pubkey); + return transaction; + + } + + Poco::AutoPtr TransactionTransfer::createInbound(const std::string& memo) + { + const char* function_name = "TransactionTransfer::createInbound"; + auto mm = MemoryManager::getInstance(); + + if (!mProtoTransfer.has_outbound()) { return nullptr; } - auto transaction = Transaction::createTransfer(sender, receiver_pubkey, groups[0], inbound.sender().amount(), memo, false); - mm->releaseMemory(receiver_pubkey); - return transaction[0]; + // Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo + //Transaction::createTransfer() + auto outbound = mProtoTransfer.outbound(); + auto sender_pubkey = mm->getFreeMemory(outbound.sender().pubkey().size()); + memcpy(*sender_pubkey, outbound.sender().pubkey().data(), outbound.sender().pubkey().size()); + auto receiver_pubkey = mm->getFreeMemory(outbound.receiver().size()); + memcpy(*receiver_pubkey, outbound.receiver().data(), outbound.receiver().size()); + + auto body = TransactionBody::create( + memo, sender_pubkey, receiver_pubkey, + outbound.sender().amount(), mOwnGroupAlias, TRANSFER_CROSS_GROUP_INBOUND, + DataTypeConverter::convertFromProtoTimestamp(outbound.paired_transaction_id()) + ); + + auto transaction = Poco::AutoPtr(new Transaction(body)); + transaction->setTopicIdByGroup(mTargetGroupAlias); + + mm->releaseMemory(receiver_pubkey); + mm->releaseMemory(sender_pubkey); + return transaction; } const std::string& TransactionTransfer::getKontoNameCell(int index) diff --git a/src/cpp/model/gradido/TransactionTransfer.h b/src/cpp/model/gradido/TransactionTransfer.h index 558c8a7db..57259059f 100644 --- a/src/cpp/model/gradido/TransactionTransfer.h +++ b/src/cpp/model/gradido/TransactionTransfer.h @@ -22,6 +22,13 @@ namespace model { class Transaction; + enum TransactionTransferType + { + TRANSFER_LOCAL, + TRANSFER_CROSS_GROUP_INBOUND, + TRANSFER_CROSS_GROUP_OUTBOUND + }; + class TransactionTransfer : public TransactionBase { public: @@ -37,10 +44,15 @@ namespace model { std::string getTargetGroupAlias(); bool isInbound() { return mProtoTransfer.has_inbound(); } + bool isOutbound() { return mProtoTransfer.has_outbound(); } Poco::AutoPtr createOutbound(const std::string& memo); + Poco::AutoPtr createInbound(const std::string& memo); void transactionAccepted(Poco::AutoPtr user); + inline void setOwnGroupAlias(const std::string& ownGroupAlias) { mOwnGroupAlias = ownGroupAlias; } + inline void setTargetGroupAlias(const std::string& targetGroupAlias) { mTargetGroupAlias = targetGroupAlias; } + protected: const static std::string mInvalidIndexMessage; @@ -62,6 +74,8 @@ namespace model { const proto::gradido::GradidoTransfer& mProtoTransfer; std::vector mKontoTable; + std::string mOwnGroupAlias; + std::string mTargetGroupAlias; }; } } diff --git a/src/cpsp/adminNodeServerTest.cpsp b/src/cpsp/adminNodeServerTest.cpsp index f504caa0d..6bebc8c06 100644 --- a/src/cpsp/adminNodeServerTest.cpsp +++ b/src/cpsp/adminNodeServerTest.cpsp @@ -29,11 +29,14 @@ enum PageType const char* pageName = "Node Server Test"; PageType page = PAGE_CHOOSE_TEST; Poco::AutoPtr node_server; + Poco::AutoPtr node_server2; Poco::AutoPtr user; Poco::AutoPtr hedera_topic; - int hedera_timeout = 9; + Poco::AutoPtr hedera_topic2; + int hedera_timeout = 4; + int sleep_ms_between_transactions = 1000; - bool steps[6]; memset(steps, 1, 6 * sizeof(bool)); + bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); if(!form.empty()) @@ -45,6 +48,13 @@ enum PageType node_server = controller::NodeServer::load(node_server_id); } } + node_server_id_string = form.get("test-node-servers2", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server2 = controller::NodeServer::load(node_server_id); + } + } auto topic_id_string = form.get("test-hedera-topic", ""); if(topic_id_string != "") { int topic_id = 0; @@ -52,18 +62,25 @@ enum PageType hedera_topic = controller::HederaTopic::load(topic_id); } } + topic_id_string = form.get("test-hedera-topic2", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic2 = controller::HederaTopic::load(topic_id); + } + } auto test_timeout_string = form.get("test-timeout", ""); if(test_timeout_string != "") { DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); } auto submit = form.get("submit", ""); - if(submit == "Run 4-Test") { + if(submit == "Run 6-Test") { page = PAGE_RUN_4_SET_TEST; } else if(submit == "json-rpc getTransactions") { page = PAGE_GET_TRANSACTION_RPC_CALL; } std::string step_temp; - for(int i = 0; i < 6; i++) { + for(int i = 0; i < 8; i++) { std::string name = "step-"; name += std::to_string(i+2); step_temp = form.get(name, ""); @@ -83,52 +100,86 @@ enum PageType
- +
style="display:block" <% } %>>
-

Test 4-Set (2 AddMember, Creation, Transfer) +

Test 6-Set (3 AddMember, Creation, 2 Transfer)

-

1. Create two new accounts and show user public keys for comparisation

+

1. Create three new accounts and show user public keys for comparisation

checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)

checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user

checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user

-

checked="checked" <% } %> name="step-6" value="1"/> 6. Wait x seconds to give hedera time to process transactions

-

checked="checked" <% } %> name="step-7" value="1"/> 7. Ask choosen node for transaction and print result

- - - <% if(node_servers.size() == 0) { %> - Edit Node-Servers - <% } %> - checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)

+

checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user

+

checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions

+

checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result

+
+ Group 1 + + <% if(node_servers.size() == 0) { %> + Edit Node-Servers <% } %> - - - <% if(hedera_topics.size() == 0) { %> - Edit Hedera-Topics - <% } %> - + <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { + auto model = (*it)->getModel(); + %> + + <% } %> + + + <% if(hedera_topics.size() == 0) { %> + Edit Hedera-Topics <% } %> - + +
+
+ Group 2 + + <% if(node_servers.size() == 0) { %> + Edit Node-Servers + <% } %> + + + <% if(hedera_topics.size() == 0) { %> + Edit Hedera-Topics + <% } %> + +
+ seconds - +
@@ -156,11 +207,13 @@ enum PageType <% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %>
  • -

    1. Create two new accounts and show user public keys for comparisation:

    +

    1. Create three new accounts and show user public keys for comparisation:

    <% Profiler time2; auto group_id = hedera_topic->getModel()->getGroupId(); + auto group_id2 = hedera_topic2->getModel()->getGroupId(); auto user_group = controller::Group::load(group_id); + auto user_group2 = controller::Group::load(group_id2); auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; @@ -176,9 +229,21 @@ enum PageType auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); user_2->setGradidoKeyPair(gradido_key_pair_2); user_2->login(password2); + + std::string password3 = "jaue_skaiellasealaK"; + auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); + auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); + user_3->setGradidoKeyPair(gradido_key_pair_3); + user_3->login(password3); %> -

    User 1: <%= user_1->getPublicHex() %>

    -

    User 2: <%= user_2->getPublicHex() %>

    +
    <%= user_group->getModel()->getName() %> +

    User 1: <%= user_1->getPublicHex() %>

    +

    User 2: <%= user_2->getPublicHex() %>

    +
    +
    <%= user_group2->getModel()->getName() %> +

    User 3: <%= user_3->getPublicHex() %>

    +

    Time: <%= time2.string() %>

  • @@ -207,6 +272,8 @@ enum PageType auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); transaction2->sign(user_2); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction2->sign(user_1); auto transaction2_json = transaction2->getTransactionAsJson(true); %> @@ -222,6 +289,8 @@ enum PageType

    skipped

    <% } else { auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction3->sign(user_1); auto transaction3_json = transaction3->getTransactionAsJson(true); %> @@ -239,7 +308,7 @@ enum PageType auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(hedera_timeout * 100); + Poco::Thread::sleep(sleep_ms_between_transactions); transaction4[0]->sign(user_2); auto transaction4_json = transaction4[0]->getTransactionAsJson(true); %> @@ -248,17 +317,60 @@ enum PageType

    Time: <%= time2.string() %>

  • -

    6. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions

    - <% if(!steps[4]) { %> +

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    + <% + time2.reset(); + if(!steps[4]) { %> +

    skipped

    + <% } else { + auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); + transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction5->sign(user_3); + auto transaction5_json = transaction5->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %>

    + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    7. Send a cross group transfer from second user to third user signed by second user

    + <% + time2.reset(); + if(!steps[5]) { %> +

    skipped

    + <% } else { + auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); + auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); + if(!transaction6.size()) { + %> + + <% + } else { + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction6[0]->sign(user_2); + auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %>

    + <% } %> + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions

    + <% if(!steps[6]) { %>

    skipped

    <% } else { Poco::Thread::sleep(hedera_timeout * 1000); } %>
  • -

    7. Ask choosen node for transaction and print result

    +

    9. Ask choosen node for transaction and print result

    <% time2.reset(); - if(!steps[5] || node_server.isNull()) { + if(!steps[7] || node_server.isNull()) { %>

    skipped

    <% } else { auto node_server_model = node_server->getModel(); From 1865e9e814bcd17b72e41de75f0b83c9df6a35bf Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Mon, 8 Feb 2021 08:31:02 +0100 Subject: [PATCH 181/195] show both transaction json by sending cross group transaction --- .../HTTPInterface/AdminNodeServerTestPage.cpp | 48 ++++++++++++------- src/cpp/model/gradido/Transaction.cpp | 1 + src/cpp/model/gradido/Transaction.h | 3 +- src/cpsp/adminNodeServerTest.cpsp | 5 ++ 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp index a406800f5..0f06b8c79 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp @@ -718,33 +718,45 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::Thread::sleep(sleep_ms_between_transactions); transaction6[0]->sign(user_2); auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + auto paired_transaction = transaction6[0]->getPairedTransaction(); responseStream << "\n"; responseStream << "\t\t\t\t\t

    "; -#line 357 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 358 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_json) ); responseStream << "

    \t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 359 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(!paired_transaction.isNull()) { + auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); + responseStream << "

    "; +#line 361 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t\t\t"; +#line 362 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 358 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 363 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t"; -#line 359 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 364 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << " \n"; responseStream << "\t\t\t

    Time: "; -#line 360 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 365 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    8. Wait "; -#line 363 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 368 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( hedera_timeout ); responseStream << " seconds to give hedera time to process transactions

    \n"; responseStream << "\t\t\t"; -#line 364 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 369 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(!steps[6]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 366 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 371 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { Poco::Thread::sleep(hedera_timeout * 1000); } responseStream << "\n"; @@ -752,12 +764,12 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    9. Ask choosen node for transaction and print result

    \n"; responseStream << "\t\t\t"; -#line 372 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 377 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[7] || node_server.isNull()) { responseStream << "

    skipped

    \n"; responseStream << "\t\t\t"; -#line 375 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 380 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto node_server_model = node_server->getModel(); JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); @@ -770,20 +782,20 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 391 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 391 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 389 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 394 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 392 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 397 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { Profiler time3; auto node_server_model = node_server->getModel(); @@ -798,23 +810,23 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t"; -#line 405 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 410 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 405 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 410 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t

Time: "; -#line 408 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 413 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time3.string() ); responseStream << "

\n"; responseStream << "\t"; -#line 409 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 414 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\n"; responseStream << "
\n"; responseStream << "\n"; // begin include footer.cpsp diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index 70fc217cb..5fb937688 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -412,6 +412,7 @@ namespace model { if (!transaction.isNull()) { transaction->sign(user); // dirty hack because gn crashes if its get transactions out of order + mPairedTransaction = transaction; Poco::Thread::sleep(1000); } else { diff --git a/src/cpp/model/gradido/Transaction.h b/src/cpp/model/gradido/Transaction.h index c8147a6a1..109f34e48 100644 --- a/src/cpp/model/gradido/Transaction.h +++ b/src/cpp/model/gradido/Transaction.h @@ -60,12 +60,13 @@ namespace model { bool needSomeoneToSign(Poco::AutoPtr user); std::string getTransactionAsJson(bool replaceBase64WithHex = false); + inline Poco::AutoPtr getPairedTransaction() { return mPairedTransaction; } bool setTopicIdByGroup(const std::string& alias); protected: - + Poco::AutoPtr mPairedTransaction; Poco::AutoPtr mTransactionBody; proto::gradido::GradidoTransaction mProtoTransaction; diff --git a/src/cpsp/adminNodeServerTest.cpsp b/src/cpsp/adminNodeServerTest.cpsp index 6bebc8c06..59d5430d2 100644 --- a/src/cpsp/adminNodeServerTest.cpsp +++ b/src/cpsp/adminNodeServerTest.cpsp @@ -353,8 +353,13 @@ enum PageType Poco::Thread::sleep(sleep_ms_between_transactions); transaction6[0]->sign(user_2); auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + auto paired_transaction = transaction6[0]->getPairedTransaction(); %>

<%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %>

+ <% if(!paired_transaction.isNull()) { + auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); + %>

<%= DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) %>

+ <% } %> <% } %> <% } %>

Time: <%= time2.string() %>

From 8489dfac8bbfc9ce0917a15860680d13b7158a65 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 2 Mar 2021 09:12:22 +0100 Subject: [PATCH 182/195] add test part timeout option for node server test --- .../HTTPInterface/AdminNodeServerTestPage.cpp | 1723 +++++++++-------- .../HTTPInterface/AdminNodeServerTestPage.h | 36 +- src/cpsp/adminNodeServerTest.cpsp | 842 ++++---- 3 files changed, 1308 insertions(+), 1293 deletions(-) diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp index 0f06b8c79..84c63a508 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp @@ -1,857 +1,866 @@ -#include "AdminNodeServerTestPage.h" -#include "Poco/Net/HTTPServerRequest.h" -#include "Poco/Net/HTTPServerResponse.h" -#include "Poco/Net/HTMLForm.h" -#include "Poco/DeflatingStream.h" - - -#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - -#include "../controller/NodeServer.h" -#include "../controller/User.h" -#include "../controller/HederaTopic.h" -#include "../lib/DataTypeConverter.h" -#include "../lib/Profiler.h" -#include "../lib/JsonRPCRequest.h" -#include "../model/gradido/Transaction.h" - -#include "Poco/Thread.h" -#include "Poco/DateTime.h" -#include "Poco/JSON/Stringifier.h" - -enum PageType -{ - PAGE_CHOOSE_TEST, - PAGE_RUN_4_SET_TEST, - PAGE_GET_TRANSACTION_RPC_CALL -}; - -#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - -#include "../ServerConfig.h" - - -void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) -{ - response.setChunkedTransferEncoding(true); - response.setContentType("text/html"); - bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); - if (_compressResponse) response.set("Content-Encoding", "gzip"); - - Poco::Net::HTMLForm form(request, request.stream()); -#line 28 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - const char* pageName = "Node Server Test"; - PageType page = PAGE_CHOOSE_TEST; - Poco::AutoPtr node_server; - Poco::AutoPtr node_server2; - Poco::AutoPtr user; - Poco::AutoPtr hedera_topic; - Poco::AutoPtr hedera_topic2; - int hedera_timeout = 4; - int sleep_ms_between_transactions = 1000; - - bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); - - - if(!form.empty()) - { - auto node_server_id_string = form.get("test-node-servers", ""); - if(node_server_id_string != "") { - int node_server_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { - node_server = controller::NodeServer::load(node_server_id); - } - } - node_server_id_string = form.get("test-node-servers2", ""); - if(node_server_id_string != "") { - int node_server_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { - node_server2 = controller::NodeServer::load(node_server_id); - } - } - auto topic_id_string = form.get("test-hedera-topic", ""); - if(topic_id_string != "") { - int topic_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { - hedera_topic = controller::HederaTopic::load(topic_id); - } - } - topic_id_string = form.get("test-hedera-topic2", ""); - if(topic_id_string != "") { - int topic_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { - hedera_topic2 = controller::HederaTopic::load(topic_id); - } - } - auto test_timeout_string = form.get("test-timeout", ""); - if(test_timeout_string != "") { - DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); - } - auto submit = form.get("submit", ""); - if(submit == "Run 6-Test") { - page = PAGE_RUN_4_SET_TEST; - } else if(submit == "json-rpc getTransactions") { - page = PAGE_GET_TRANSACTION_RPC_CALL; - } - std::string step_temp; - for(int i = 0; i < 8; i++) { - std::string name = "step-"; - name += std::to_string(i+2); - step_temp = form.get(name, ""); - if(step_temp == "1") { - steps[i] = true; - } else { - steps[i] = false; - } - } - } - - auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE); - auto hedera_topics = controller::HederaTopic::listAll(); - -#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - - bool withMaterialIcons = false; - std::ostream& _responseStream = response.send(); - Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); - std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; - responseStream << "\n"; - // begin include header_large.cpsp - responseStream << "\n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "Gradido Login Server: "; -#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - responseStream << ( pageName ); - responseStream << "\n"; - responseStream << "\n"; -#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - if(withMaterialIcons) { responseStream << "\n"; - responseStream << "\n"; -#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - } responseStream << "\n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << "
\n"; - responseStream << "\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t
    \n"; - responseStream << "\t\t\t\t\t"; -#line 22 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - if(!user.isNull()) { responseStream << "\n"; - responseStream << "\t\t\t\t\t\t
  • getGroupBaseUrl() ); - responseStream << "/\">Startseite
  • \n"; - responseStream << "\t\t\t\t\t"; -#line 24 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\t
  • Gruppen
  • \n"; - responseStream << "\t\t\t\t\t
  • Node Server
  • \n"; - responseStream << "\t\t\t\t\t
  • Hedera Accounts
  • \n"; - responseStream << "\t\t\t\t\t
  • Hedera Topics
  • \n"; - responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t
\n"; - responseStream << "\t\t
"; - // end include header_large.cpsp - responseStream << "\n"; -#line 99 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( getErrorsHtml() ); - responseStream << "\n"; - responseStream << "
\n"; - responseStream << "\t\n"; - responseStream << "\t
\n"; - responseStream << "\t \n"; - responseStream << "\t \n"; - responseStream << "\t
\n"; - responseStream << "\t
\n"; - responseStream << "\t\t
\n"; - responseStream << "\t\t\t

Test 6-Set (3 AddMember, Creation, 2 Transfer)\n"; - responseStream << "\t\t

\n"; - responseStream << "\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t

1. Create three new accounts and show user public keys for comparisation

\n"; - responseStream << "\t\t\t\t

2. Send a add-member transaction to hedera topic with one signature (first user)

\n"; - responseStream << "\t\t\t\t

3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

\n"; - responseStream << "\t\t\t\t

4. Send a creation transaction to second user, signed by first user

\n"; - responseStream << "\t\t\t\t

5. Send a transfer transaction from second user to first user signed by second user

\n"; - responseStream << "\t\t\t\t

6. Send a add-member transaction to hedera topic 2 with one signature (third user)

\n"; - responseStream << "\t\t\t\t

7. Send a cross group transfer from second user to third user signed by second user

\n"; - responseStream << "\t\t\t\t

8. Wait x seconds to give hedera time to process transactions

\n"; - responseStream << "\t\t\t\t

9. Ask choosen node for transaction and print result

\n"; - responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t\t\tGroup 1 \n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 124 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(node_servers.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\t\tEdit Node-Servers\n"; - responseStream << "\t\t\t\t\t"; -#line 126 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 135 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(hedera_topics.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\t\tEdit Hedera-Topics\n"; - responseStream << "\t\t\t\t\t"; -#line 137 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t\t\tGroup 2 \n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 153 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(node_servers.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\t\tEdit Node-Servers\n"; - responseStream << "\t\t\t\t\t"; -#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(hedera_topics.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\t\tEdit Hedera-Topics\n"; - responseStream << "\t\t\t\t\t"; -#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t seconds \n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t
\n"; - responseStream << "\t
\n"; - responseStream << "\t
\n"; - responseStream << "\t\t
\n"; - responseStream << "\t\t\t

Test 4-Set (2 AddMember, Creation, Transfer)\n"; - responseStream << "\t\t

\n"; - responseStream << "\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t"; -#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(node_servers.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\tEdit Node-Servers\n"; - responseStream << "\t\t\t\t"; -#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t
\n"; - responseStream << "\t
\n"; - responseStream << "\t"; -#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { responseStream << "\n"; - responseStream << "\t
    \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    1. Create three new accounts and show user public keys for comparisation:

    \n"; - responseStream << "\t\t\t"; -#line 211 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - Profiler time2; - auto group_id = hedera_topic->getModel()->getGroupId(); - auto group_id2 = hedera_topic2->getModel()->getGroupId(); - auto user_group = controller::Group::load(group_id); - auto user_group2 = controller::Group::load(group_id2); - auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - - std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; - auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id); - auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1); - user_1->setGradidoKeyPair(gradido_key_pair_1); - user_1->login(password1); - - std::string password2 = "uweia8saiSale,dsasA"; - auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id); - auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); - user_2->setGradidoKeyPair(gradido_key_pair_2); - user_2->login(password2); - - std::string password3 = "jaue_skaiellasealaK"; - auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); - auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); - user_3->setGradidoKeyPair(gradido_key_pair_3); - user_3->login(password3); - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t
    "; -#line 240 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( user_group->getModel()->getName() ); - responseStream << "\n"; - responseStream << "\t\t\t\t

    User 1: "; -#line 241 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( user_1->getPublicHex() ); - responseStream << "

    \n"; - responseStream << "\t\t\t\t

    User 2: "; -#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( user_2->getPublicHex() ); - responseStream << "

    \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t
    "; -#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( user_group2->getModel()->getName() ); - responseStream << "\n"; - responseStream << "\t\t\t\t

    User 3: "; -#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( user_3->getPublicHex() ); - responseStream << "

    \n"; - responseStream << "\t\t\t
    \n"; - responseStream << "\t\t\t

    Time: "; -#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "\n"; - responseStream << "\t\t

  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    2. Send a add-member transaction to hedera topic with one signature (first user)

    \n"; - responseStream << "\t\t\t"; -#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - time2.reset(); - if(!steps[0]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 255 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); - transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); - transaction1->sign(user_1); - auto transaction1_json = transaction1->getTransactionAsJson(true); - responseStream << "\n"; - responseStream << "\t\t\t

    "; -#line 261 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction1_json) ); - responseStream << "

    \n"; - responseStream << "\t\t\t"; -#line 262 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t

    Time: "; -#line 263 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "\n"; - responseStream << "\t\t

  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

    \n"; - responseStream << "\t\t\t"; -#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - time2.reset(); - if(!steps[1]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 271 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); - transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); - transaction2->sign(user_2); - // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction2->sign(user_1); - auto transaction2_json = transaction2->getTransactionAsJson(true); - responseStream << "\n"; - responseStream << "\t\t\t

    "; -#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction2_json) ); - responseStream << "

    \n"; - responseStream << "\t\t\t"; -#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t

    Time: "; -#line 282 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "\n"; - responseStream << "\t\t

  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    4. Send a creation transaction to second user, signed by first user

    \n"; - responseStream << "\t\t\t"; -#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - time2.reset(); - if(!steps[2]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); - // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction3->sign(user_1); - auto transaction3_json = transaction3->getTransactionAsJson(true); - responseStream << "\n"; - responseStream << "\t\t\t

    "; -#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction3_json) ); - responseStream << "

    \n"; - responseStream << "\t\t\t"; -#line 298 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t

    Time: "; -#line 299 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "

    \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    5. Send a transfer transaction from second user to first user signed by second user

    \n"; - responseStream << "\t\t\t"; -#line 303 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - time2.reset(); - if(!steps[3]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 307 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); - auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); - // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction4[0]->sign(user_2); - auto transaction4_json = transaction4[0]->getTransactionAsJson(true); - responseStream << "\n"; - responseStream << "\t\t\t

    "; -#line 315 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction4_json) ); - responseStream << "

    \n"; - responseStream << "\t\t\t"; -#line 316 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t

    Time: "; -#line 317 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "

    \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    \n"; - responseStream << "\t\t\t"; -#line 321 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - time2.reset(); - if(!steps[4]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 325 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); - transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction5->sign(user_3); - auto transaction5_json = transaction5->getTransactionAsJson(true); - responseStream << "\n"; - responseStream << "\t\t\t

    "; -#line 332 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction5_json) ); - responseStream << "

    \n"; - responseStream << "\t\t\t"; -#line 333 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t

    Time: "; -#line 334 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "

    \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    7. Send a cross group transfer from second user to third user signed by second user

    \n"; - responseStream << "\t\t\t"; -#line 338 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - time2.reset(); - if(!steps[5]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 342 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); - auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); - if(!transaction6.size()) { - responseStream << "\n"; - responseStream << "\t\t\t\t
    \n"; - responseStream << "\t\t\t\t\treport_problem\n"; - responseStream << "\t\t\t\t\tError creating Transaction\n"; - responseStream << "\t\t\t\t
    \n"; - responseStream << "\t\t\t\t"; -#line 351 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - } else { - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction6[0]->sign(user_2); - auto transaction6_json = transaction6[0]->getTransactionAsJson(true); - auto paired_transaction = transaction6[0]->getPairedTransaction(); - responseStream << "\n"; - responseStream << "\t\t\t\t\t

    "; -#line 358 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_json) ); - responseStream << "

    \t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 359 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(!paired_transaction.isNull()) { - auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); - responseStream << "

    "; -#line 361 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) ); - responseStream << "

    \n"; - responseStream << "\t\t\t\t\t"; -#line 362 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t"; -#line 363 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t"; -#line 364 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << " \n"; - responseStream << "\t\t\t

    Time: "; -#line 365 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "

    \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    8. Wait "; -#line 368 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( hedera_timeout ); - responseStream << " seconds to give hedera time to process transactions

    \n"; - responseStream << "\t\t\t"; -#line 369 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(!steps[6]) { responseStream << "\n"; - responseStream << "\t\t\t\t

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 371 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - Poco::Thread::sleep(hedera_timeout * 1000); - } responseStream << "\n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    9. Ask choosen node for transaction and print result

    \n"; - responseStream << "\t\t\t"; -#line 377 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - time2.reset(); - if(!steps[7] || node_server.isNull()) { - responseStream << "

    skipped

    \n"; - responseStream << "\t\t\t"; -#line 380 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else { - auto node_server_model = node_server->getModel(); - JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); - Poco::JSON::Object params; - params.set("groupAlias", user_group->getModel()->getAlias()); - params.set("lastKnownSequenceNumber", 0); - auto gn_answear = jsonrpc.request("getTransactions", params); - if(!gn_answear.isNull()) { - std::stringstream ss; - Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); - std::string answear_string = ss.str(); responseStream << "\n"; - responseStream << "\t\t\t\t\t"; -#line 391 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 391 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - } - } responseStream << "\n"; - responseStream << "\t\t\t

    Time: "; -#line 394 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time2.string() ); - responseStream << "

    \n"; - responseStream << "\t\t
  • \n"; - responseStream << "\t
\n"; - responseStream << "\t"; -#line 397 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { - Profiler time3; - auto node_server_model = node_server->getModel(); - auto user_group = controller::Group::load(node_server_model->getGroupId()); - JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); - Poco::JSON::Object params; - params.set("groupAlias", user_group->getModel()->getAlias()); - params.set("lastKnownSequenceNumber", 0); - auto gn_answear = jsonrpc.request("getTransactions", params); - if(!gn_answear.isNull()) { - std::stringstream ss; - Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); - std::string answear_string = ss.str(); responseStream << "\n"; - responseStream << "\t\t\t"; -#line 410 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 410 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - - } - responseStream << "\n"; - responseStream << "\t\t

Time: "; -#line 413 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - responseStream << ( time3.string() ); - responseStream << "

\n"; - responseStream << "\t"; -#line 414 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\n"; - responseStream << "
\n"; - responseStream << "\n"; - // begin include footer.cpsp - responseStream << "
\n"; - responseStream << "

Copyright © Gradido 2020

\n"; - responseStream << "
\n"; - responseStream << "
\n"; - responseStream << "
\n"; - responseStream << " "; -#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" - responseStream << ( mTimeProfiler.string() ); - responseStream << "\n"; - responseStream << "
\n"; - responseStream << "
\n"; - responseStream << "

Login Server in Entwicklung

\n"; - responseStream << "

Alpha "; -#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" - responseStream << ( ServerConfig::g_versionString ); - responseStream << "

\n"; - responseStream << "
\n"; - responseStream << "
\n"; - responseStream << "\n"; - responseStream << "\n"; - responseStream << ""; - // end include footer.cpsp - responseStream << "\n"; - if (_compressResponse) _gzipStream.close(); -} +#include "AdminNodeServerTestPage.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + +#include "../controller/NodeServer.h" +#include "../controller/User.h" +#include "../controller/HederaTopic.h" +#include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/JsonRPCRequest.h" +#include "../model/gradido/Transaction.h" + +#include "Poco/Thread.h" +#include "Poco/DateTime.h" +#include "Poco/JSON/Stringifier.h" + +enum PageType +{ + PAGE_CHOOSE_TEST, + PAGE_RUN_4_SET_TEST, + PAGE_GET_TRANSACTION_RPC_CALL +}; + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + +#include "../ServerConfig.h" + + +void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 28 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + const char* pageName = "Node Server Test"; + PageType page = PAGE_CHOOSE_TEST; + Poco::AutoPtr node_server; + Poco::AutoPtr node_server2; + Poco::AutoPtr user; + Poco::AutoPtr hedera_topic; + Poco::AutoPtr hedera_topic2; + int hedera_timeout = 4; + int sleep_ms_between_transactions = 1000; + + bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); + + + if(!form.empty()) + { + auto node_server_id_string = form.get("test-node-servers", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server = controller::NodeServer::load(node_server_id); + } + } + node_server_id_string = form.get("test-node-servers2", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server2 = controller::NodeServer::load(node_server_id); + } + } + auto topic_id_string = form.get("test-hedera-topic", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic = controller::HederaTopic::load(topic_id); + } + } + topic_id_string = form.get("test-hedera-topic2", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic2 = controller::HederaTopic::load(topic_id); + } + } + auto test_timeout_string = form.get("test-timeout", ""); + if(test_timeout_string != "") { + DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); + } + auto test_part_timeout_string = form.get("test-part-timeout", ""); + if(test_part_timeout_string != "") { + DataTypeConverter::strToInt(test_part_timeout_string, sleep_ms_between_transactions); + } + auto submit = form.get("submit", ""); + if(submit == "Run 6-Test") { + page = PAGE_RUN_4_SET_TEST; + } else if(submit == "json-rpc getTransactions") { + page = PAGE_GET_TRANSACTION_RPC_CALL; + } + std::string step_temp; + for(int i = 0; i < 8; i++) { + std::string name = "step-"; + name += std::to_string(i+2); + step_temp = form.get(name, ""); + if(step_temp == "1") { + steps[i] = true; + } else { + steps[i] = false; + } + } + } + + auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE); + auto hedera_topics = controller::HederaTopic::listAll(); + +#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + + bool withMaterialIcons = false; + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_large.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; +#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(withMaterialIcons) { responseStream << "\n"; + responseStream << "\n"; +#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\t"; +#line 22 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + if(!user.isNull()) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t
  • getGroupBaseUrl() ); + responseStream << "/\">Startseite
  • \n"; + responseStream << "\t\t\t\t\t"; +#line 24 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t
  • Gruppen
  • \n"; + responseStream << "\t\t\t\t\t
  • Node Server
  • \n"; + responseStream << "\t\t\t\t\t
  • Hedera Accounts
  • \n"; + responseStream << "\t\t\t\t\t
  • Hedera Topics
  • \n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t
"; + // end include header_large.cpsp + responseStream << "\n"; +#line 103 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t\n"; + responseStream << "\t
\n"; + responseStream << "\t \n"; + responseStream << "\t \n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

Test 6-Set (3 AddMember, Creation, 2 Transfer)\n"; + responseStream << "\t\t

\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t

1. Create three new accounts and show user public keys for comparisation

\n"; + responseStream << "\t\t\t\t

2. Send a add-member transaction to hedera topic with one signature (first user)

\n"; + responseStream << "\t\t\t\t

3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

\n"; + responseStream << "\t\t\t\t

4. Send a creation transaction to second user, signed by first user

\n"; + responseStream << "\t\t\t\t

5. Send a transfer transaction from second user to first user signed by second user

\n"; + responseStream << "\t\t\t\t

6. Send a add-member transaction to hedera topic 2 with one signature (third user)

\n"; + responseStream << "\t\t\t\t

7. Send a cross group transfer from second user to third user signed by second user

\n"; + responseStream << "\t\t\t\t

8. Wait x seconds to give hedera time to process transactions

\n"; + responseStream << "\t\t\t\t

9. Ask choosen node for transaction and print result

\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tGroup 1 \n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 128 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(node_servers.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Node-Servers\n"; + responseStream << "\t\t\t\t\t"; +#line 130 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(hedera_topics.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Hedera-Topics\n"; + responseStream << "\t\t\t\t\t"; +#line 141 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tGroup 2 \n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 157 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(node_servers.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Node-Servers\n"; + responseStream << "\t\t\t\t\t"; +#line 159 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 168 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(hedera_topics.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Hedera-Topics\n"; + responseStream << "\t\t\t\t\t"; +#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t seconds \n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t ms\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

Test 4-Set (2 AddMember, Creation, Transfer)\n"; + responseStream << "\t\t

\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t"; +#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(node_servers.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\tEdit Node-Servers\n"; + responseStream << "\t\t\t\t"; +#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t"; +#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { responseStream << "\n"; + responseStream << "\t
    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    1. Create three new accounts and show user public keys for comparisation:

    \n"; + responseStream << "\t\t\t"; +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + Profiler time2; + auto group_id = hedera_topic->getModel()->getGroupId(); + auto group_id2 = hedera_topic2->getModel()->getGroupId(); + auto user_group = controller::Group::load(group_id); + auto user_group2 = controller::Group::load(group_id2); + auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + + std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; + auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id); + auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1); + user_1->setGradidoKeyPair(gradido_key_pair_1); + user_1->login(password1); + + std::string password2 = "uweia8saiSale,dsasA"; + auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id); + auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); + user_2->setGradidoKeyPair(gradido_key_pair_2); + user_2->login(password2); + + std::string password3 = "jaue_skaiellasealaK"; + auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); + auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); + user_3->setGradidoKeyPair(gradido_key_pair_3); + user_3->login(password3); + responseStream << "\t\t\t\n"; + responseStream << "\t\t\t
    "; +#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_group->getModel()->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t

    User 1: "; +#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_1->getPublicHex() ); + responseStream << "

    \n"; + responseStream << "\t\t\t\t

    User 2: "; +#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_2->getPublicHex() ); + responseStream << "

    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t
    "; +#line 250 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_group2->getModel()->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t

    User 3: "; +#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_3->getPublicHex() ); + responseStream << "

    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t

    Time: "; +#line 253 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "\n"; + responseStream << "\t\t

  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    2. Send a add-member transaction to hedera topic with one signature (first user)

    \n"; + responseStream << "\t\t\t"; +#line 257 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[0]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 261 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); + transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + transaction1->sign(user_1); + auto transaction1_json = transaction1->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction1_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "\n"; + responseStream << "\t\t

  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

    \n"; + responseStream << "\t\t\t"; +#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[1]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); + transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); + transaction2->sign(user_2); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction2->sign(user_1); + auto transaction2_json = transaction2->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction2_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 287 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 288 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "\n"; + responseStream << "\t\t

  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    4. Send a creation transaction to second user, signed by first user

    \n"; + responseStream << "\t\t\t"; +#line 292 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[2]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 296 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction3->sign(user_1); + auto transaction3_json = transaction3->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 303 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction3_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 304 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 305 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    5. Send a transfer transaction from second user to first user signed by second user

    \n"; + responseStream << "\t\t\t"; +#line 309 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[3]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 313 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); + auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction4[0]->sign(user_2); + auto transaction4_json = transaction4[0]->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 321 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction4_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 322 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 323 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    \n"; + responseStream << "\t\t\t"; +#line 327 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[4]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 331 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); + transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction5->sign(user_3); + auto transaction5_json = transaction5->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 338 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction5_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 339 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 340 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    7. Send a cross group transfer from second user to third user signed by second user

    \n"; + responseStream << "\t\t\t"; +#line 344 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[5]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 348 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); + auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); + if(!transaction6.size()) { + responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\treport_problem\n"; + responseStream << "\t\t\t\t\tError creating Transaction\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t"; +#line 357 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } else { + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction6[0]->sign(user_2); + auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + auto paired_transaction = transaction6[0]->getPairedTransaction(); + responseStream << "\n"; + responseStream << "\t\t\t\t\t

    "; +#line 364 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_json) ); + responseStream << "

    \t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 365 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(!paired_transaction.isNull()) { + auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); + responseStream << "

    "; +#line 367 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t\t\t"; +#line 368 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t"; +#line 369 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t"; +#line 370 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " \n"; + responseStream << "\t\t\t

    Time: "; +#line 371 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    8. Wait "; +#line 374 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( hedera_timeout ); + responseStream << " seconds to give hedera time to process transactions

    \n"; + responseStream << "\t\t\t"; +#line 375 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(!steps[6]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 377 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + Poco::Thread::sleep(hedera_timeout * 1000); + } responseStream << "\n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    9. Ask choosen node for transaction and print result

    \n"; + responseStream << "\t\t\t"; +#line 383 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + time2.reset(); + if(!steps[7] || node_server.isNull()) { + responseStream << "

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto node_server_model = node_server->getModel(); + JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); + Poco::JSON::Object params; + params.set("groupAlias", user_group->getModel()->getAlias()); + params.set("lastKnownSequenceNumber", 0); + auto gn_answear = jsonrpc.request("getTransactions", params); + if(!gn_answear.isNull()) { + std::stringstream ss; + Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); + std::string answear_string = ss.str(); responseStream << "\n"; + responseStream << "\t\t\t\t\t"; +#line 397 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); +#line 397 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 400 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t
\n"; + responseStream << "\t"; +#line 403 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { + Profiler time3; + auto node_server_model = node_server->getModel(); + auto user_group = controller::Group::load(node_server_model->getGroupId()); + JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); + Poco::JSON::Object params; + params.set("groupAlias", user_group->getModel()->getAlias()); + params.set("lastKnownSequenceNumber", 0); + auto gn_answear = jsonrpc.request("getTransactions", params); + if(!gn_answear.isNull()) { + std::stringstream ss; + Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); + std::string answear_string = ss.str(); responseStream << "\n"; + responseStream << "\t\t\t"; +#line 416 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); +#line 416 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } + responseStream << "\n"; + responseStream << "\t\t

Time: "; +#line 419 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time3.string() ); + responseStream << "

\n"; + responseStream << "\t"; +#line 420 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\n"; + responseStream << "
\n"; + responseStream << "\n"; + // begin include footer.cpsp + responseStream << "
\n"; + responseStream << "

Copyright © Gradido 2020

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << " "; +#line 6 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "

Login Server in Entwicklung

\n"; + responseStream << "

Alpha "; +#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; + responseStream << "
\n"; + responseStream << "
\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.h b/src/cpp/HTTPInterface/AdminNodeServerTestPage.h index a1ff3ad1d..12e550efa 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.h +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.h @@ -1,18 +1,18 @@ -#ifndef AdminNodeServerTestPage_INCLUDED -#define AdminNodeServerTestPage_INCLUDED - - -#include "Poco/Net/HTTPRequestHandler.h" - - -#include "PageRequestMessagedHandler.h" - - -class AdminNodeServerTestPage: public PageRequestMessagedHandler -{ -public: - void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); -}; - - -#endif // AdminNodeServerTestPage_INCLUDED +#ifndef AdminNodeServerTestPage_INCLUDED +#define AdminNodeServerTestPage_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "PageRequestMessagedHandler.h" + + +class AdminNodeServerTestPage: public PageRequestMessagedHandler +{ +public: + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminNodeServerTestPage_INCLUDED diff --git a/src/cpsp/adminNodeServerTest.cpsp b/src/cpsp/adminNodeServerTest.cpsp index 59d5430d2..a1cc0a295 100644 --- a/src/cpsp/adminNodeServerTest.cpsp +++ b/src/cpsp/adminNodeServerTest.cpsp @@ -1,418 +1,424 @@ -<%@ page class="AdminNodeServerTestPage" %> -<%@ page form="true" %> -<%@ page compressed="true" %> -<%@ page baseClass="PageRequestMessagedHandler" %> -<%@ header include="PageRequestMessagedHandler.h" %> -<%! - -#include "../controller/NodeServer.h" -#include "../controller/User.h" -#include "../controller/HederaTopic.h" -#include "../lib/DataTypeConverter.h" -#include "../lib/Profiler.h" -#include "../lib/JsonRPCRequest.h" -#include "../model/gradido/Transaction.h" - -#include "Poco/Thread.h" -#include "Poco/DateTime.h" -#include "Poco/JSON/Stringifier.h" - -enum PageType -{ - PAGE_CHOOSE_TEST, - PAGE_RUN_4_SET_TEST, - PAGE_GET_TRANSACTION_RPC_CALL -}; - -%> -<%% - const char* pageName = "Node Server Test"; - PageType page = PAGE_CHOOSE_TEST; - Poco::AutoPtr node_server; - Poco::AutoPtr node_server2; - Poco::AutoPtr user; - Poco::AutoPtr hedera_topic; - Poco::AutoPtr hedera_topic2; - int hedera_timeout = 4; - int sleep_ms_between_transactions = 1000; - - bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); - - - if(!form.empty()) - { - auto node_server_id_string = form.get("test-node-servers", ""); - if(node_server_id_string != "") { - int node_server_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { - node_server = controller::NodeServer::load(node_server_id); - } - } - node_server_id_string = form.get("test-node-servers2", ""); - if(node_server_id_string != "") { - int node_server_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { - node_server2 = controller::NodeServer::load(node_server_id); - } - } - auto topic_id_string = form.get("test-hedera-topic", ""); - if(topic_id_string != "") { - int topic_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { - hedera_topic = controller::HederaTopic::load(topic_id); - } - } - topic_id_string = form.get("test-hedera-topic2", ""); - if(topic_id_string != "") { - int topic_id = 0; - if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { - hedera_topic2 = controller::HederaTopic::load(topic_id); - } - } - auto test_timeout_string = form.get("test-timeout", ""); - if(test_timeout_string != "") { - DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); - } - auto submit = form.get("submit", ""); - if(submit == "Run 6-Test") { - page = PAGE_RUN_4_SET_TEST; - } else if(submit == "json-rpc getTransactions") { - page = PAGE_GET_TRANSACTION_RPC_CALL; - } - std::string step_temp; - for(int i = 0; i < 8; i++) { - std::string name = "step-"; - name += std::to_string(i+2); - step_temp = form.get(name, ""); - if(step_temp == "1") { - steps[i] = true; - } else { - steps[i] = false; - } - } - } - - auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE); - auto hedera_topics = controller::HederaTopic::listAll(); - -%><%@ include file="header_large.cpsp" %> -<%= getErrorsHtml() %> -
- -
- - -
-
style="display:block" <% } %>> -
-

Test 6-Set (3 AddMember, Creation, 2 Transfer) -

-
-
-

1. Create three new accounts and show user public keys for comparisation

-

checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)

-

checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

-

checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user

-

checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user

-

checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)

-

checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user

-

checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions

-

checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result

-
- Group 1 - - <% if(node_servers.size() == 0) { %> - Edit Node-Servers - <% } %> - - - <% if(hedera_topics.size() == 0) { %> - Edit Hedera-Topics - <% } %> - -
-
- Group 2 - - <% if(node_servers.size() == 0) { %> - Edit Node-Servers - <% } %> - - - <% if(hedera_topics.size() == 0) { %> - Edit Hedera-Topics - <% } %> - -
- - - seconds - -
-
-
-
style="display:block" <% } %>> -
-

Test 4-Set (2 AddMember, Creation, Transfer) -

-
-
- - <% if(node_servers.size() == 0) { %> - Edit Node-Servers - <% } %> - - -
-
-
- <% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %> -
    -
  • -

    1. Create three new accounts and show user public keys for comparisation:

    - <% - Profiler time2; - auto group_id = hedera_topic->getModel()->getGroupId(); - auto group_id2 = hedera_topic2->getModel()->getGroupId(); - auto user_group = controller::Group::load(group_id); - auto user_group2 = controller::Group::load(group_id2); - auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - - std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; - auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id); - auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1); - user_1->setGradidoKeyPair(gradido_key_pair_1); - user_1->login(password1); - - std::string password2 = "uweia8saiSale,dsasA"; - auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id); - auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); - user_2->setGradidoKeyPair(gradido_key_pair_2); - user_2->login(password2); - - std::string password3 = "jaue_skaiellasealaK"; - auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); - auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); - auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); - user_3->setGradidoKeyPair(gradido_key_pair_3); - user_3->login(password3); - %> -
    <%= user_group->getModel()->getName() %> -

    User 1: <%= user_1->getPublicHex() %>

    -

    User 2: <%= user_2->getPublicHex() %>

    -
    -
    <%= user_group2->getModel()->getName() %> -

    User 3: <%= user_3->getPublicHex() %>

    -
    -

    Time: <%= time2.string() %> -

  • -
  • -

    2. Send a add-member transaction to hedera topic with one signature (first user)

    - <% - time2.reset(); - if(!steps[0]) { %> -

    skipped

    - <% } else { - auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); - transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); - transaction1->sign(user_1); - auto transaction1_json = transaction1->getTransactionAsJson(true); - %> -

    <%= DataTypeConverter::replaceNewLineWithBr(transaction1_json) %>

    - <% } %> -

    Time: <%= time2.string() %> -

  • -
  • -

    3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

    - <% - time2.reset(); - if(!steps[1]) { %> -

    skipped

    - <% } else { - auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); - transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); - transaction2->sign(user_2); - // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction2->sign(user_1); - auto transaction2_json = transaction2->getTransactionAsJson(true); - %> -

    <%= DataTypeConverter::replaceNewLineWithBr(transaction2_json) %>

    - <% } %> -

    Time: <%= time2.string() %> -

  • -
  • -

    4. Send a creation transaction to second user, signed by first user

    - <% - time2.reset(); - if(!steps[2]) { %> -

    skipped

    - <% } else { - auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); - // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction3->sign(user_1); - auto transaction3_json = transaction3->getTransactionAsJson(true); - %> -

    <%= DataTypeConverter::replaceNewLineWithBr(transaction3_json) %>

    - <% } %> -

    Time: <%= time2.string() %>

    -
  • -
  • -

    5. Send a transfer transaction from second user to first user signed by second user

    - <% - time2.reset(); - if(!steps[3]) { %> -

    skipped

    - <% } else { - auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); - auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); - // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction4[0]->sign(user_2); - auto transaction4_json = transaction4[0]->getTransactionAsJson(true); - %> -

    <%= DataTypeConverter::replaceNewLineWithBr(transaction4_json) %>

    - <% } %> -

    Time: <%= time2.string() %>

    -
  • -
  • -

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    - <% - time2.reset(); - if(!steps[4]) { %> -

    skipped

    - <% } else { - auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); - transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction5->sign(user_3); - auto transaction5_json = transaction5->getTransactionAsJson(true); - %> -

    <%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %>

    - <% } %> -

    Time: <%= time2.string() %>

    -
  • -
  • -

    7. Send a cross group transfer from second user to third user signed by second user

    - <% - time2.reset(); - if(!steps[5]) { %> -

    skipped

    - <% } else { - auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); - auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); - if(!transaction6.size()) { - %> - - <% - } else { - Poco::Thread::sleep(sleep_ms_between_transactions); - transaction6[0]->sign(user_2); - auto transaction6_json = transaction6[0]->getTransactionAsJson(true); - auto paired_transaction = transaction6[0]->getPairedTransaction(); - %> -

    <%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %>

    - <% if(!paired_transaction.isNull()) { - auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); - %>

    <%= DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) %>

    - <% } %> - <% } %> - <% } %> -

    Time: <%= time2.string() %>

    -
  • -
  • -

    8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions

    - <% if(!steps[6]) { %> -

    skipped

    - <% } else { - Poco::Thread::sleep(hedera_timeout * 1000); - } %> -
  • -
  • -

    9. Ask choosen node for transaction and print result

    - <% time2.reset(); - if(!steps[7] || node_server.isNull()) { - %>

    skipped

    - <% } else { - auto node_server_model = node_server->getModel(); - JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); - Poco::JSON::Object params; - params.set("groupAlias", user_group->getModel()->getAlias()); - params.set("lastKnownSequenceNumber", 0); - auto gn_answear = jsonrpc.request("getTransactions", params); - if(!gn_answear.isNull()) { - std::stringstream ss; - Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); - std::string answear_string = ss.str(); %> - <%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><% - } - } %> -

    Time: <%= time2.string() %>

    -
  • -
- <% } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { - Profiler time3; - auto node_server_model = node_server->getModel(); - auto user_group = controller::Group::load(node_server_model->getGroupId()); - JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); - Poco::JSON::Object params; - params.set("groupAlias", user_group->getModel()->getAlias()); - params.set("lastKnownSequenceNumber", 0); - auto gn_answear = jsonrpc.request("getTransactions", params); - if(!gn_answear.isNull()) { - std::stringstream ss; - Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); - std::string answear_string = ss.str();%> - <%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><% - } - %> -

Time: <%= time3.string() %>

- <% } %> - -
- -<%@ include file="footer.cpsp" %> +<%@ page class="AdminNodeServerTestPage" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="PageRequestMessagedHandler" %> +<%@ header include="PageRequestMessagedHandler.h" %> +<%! + +#include "../controller/NodeServer.h" +#include "../controller/User.h" +#include "../controller/HederaTopic.h" +#include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/JsonRPCRequest.h" +#include "../model/gradido/Transaction.h" + +#include "Poco/Thread.h" +#include "Poco/DateTime.h" +#include "Poco/JSON/Stringifier.h" + +enum PageType +{ + PAGE_CHOOSE_TEST, + PAGE_RUN_4_SET_TEST, + PAGE_GET_TRANSACTION_RPC_CALL +}; + +%> +<%% + const char* pageName = "Node Server Test"; + PageType page = PAGE_CHOOSE_TEST; + Poco::AutoPtr node_server; + Poco::AutoPtr node_server2; + Poco::AutoPtr user; + Poco::AutoPtr hedera_topic; + Poco::AutoPtr hedera_topic2; + int hedera_timeout = 4; + int sleep_ms_between_transactions = 1000; + + bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); + + + if(!form.empty()) + { + auto node_server_id_string = form.get("test-node-servers", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server = controller::NodeServer::load(node_server_id); + } + } + node_server_id_string = form.get("test-node-servers2", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server2 = controller::NodeServer::load(node_server_id); + } + } + auto topic_id_string = form.get("test-hedera-topic", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic = controller::HederaTopic::load(topic_id); + } + } + topic_id_string = form.get("test-hedera-topic2", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic2 = controller::HederaTopic::load(topic_id); + } + } + auto test_timeout_string = form.get("test-timeout", ""); + if(test_timeout_string != "") { + DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); + } + auto test_part_timeout_string = form.get("test-part-timeout", ""); + if(test_part_timeout_string != "") { + DataTypeConverter::strToInt(test_part_timeout_string, sleep_ms_between_transactions); + } + auto submit = form.get("submit", ""); + if(submit == "Run 6-Test") { + page = PAGE_RUN_4_SET_TEST; + } else if(submit == "json-rpc getTransactions") { + page = PAGE_GET_TRANSACTION_RPC_CALL; + } + std::string step_temp; + for(int i = 0; i < 8; i++) { + std::string name = "step-"; + name += std::to_string(i+2); + step_temp = form.get(name, ""); + if(step_temp == "1") { + steps[i] = true; + } else { + steps[i] = false; + } + } + } + + auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE); + auto hedera_topics = controller::HederaTopic::listAll(); + +%><%@ include file="header_large.cpsp" %> +<%= getErrorsHtml() %> +
+ +
+ + +
+
style="display:block" <% } %>> +
+

Test 6-Set (3 AddMember, Creation, 2 Transfer) +

+
+
+

1. Create three new accounts and show user public keys for comparisation

+

checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)

+

checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

+

checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user

+

checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user

+

checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)

+

checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user

+

checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions

+

checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result

+
+ Group 1 + + <% if(node_servers.size() == 0) { %> + Edit Node-Servers + <% } %> + + + <% if(hedera_topics.size() == 0) { %> + Edit Hedera-Topics + <% } %> + +
+
+ Group 2 + + <% if(node_servers.size() == 0) { %> + Edit Node-Servers + <% } %> + + + <% if(hedera_topics.size() == 0) { %> + Edit Hedera-Topics + <% } %> + +
+ + + seconds + + ms + +
+
+
+
style="display:block" <% } %>> +
+

Test 4-Set (2 AddMember, Creation, Transfer) +

+
+
+ + <% if(node_servers.size() == 0) { %> + Edit Node-Servers + <% } %> + + +
+
+
+ <% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %> +
    +
  • +

    1. Create three new accounts and show user public keys for comparisation:

    + <% + Profiler time2; + auto group_id = hedera_topic->getModel()->getGroupId(); + auto group_id2 = hedera_topic2->getModel()->getGroupId(); + auto user_group = controller::Group::load(group_id); + auto user_group2 = controller::Group::load(group_id2); + auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + + std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; + auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id); + auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1); + user_1->setGradidoKeyPair(gradido_key_pair_1); + user_1->login(password1); + + std::string password2 = "uweia8saiSale,dsasA"; + auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id); + auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); + user_2->setGradidoKeyPair(gradido_key_pair_2); + user_2->login(password2); + + std::string password3 = "jaue_skaiellasealaK"; + auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); + auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); + user_3->setGradidoKeyPair(gradido_key_pair_3); + user_3->login(password3); + %> +
    <%= user_group->getModel()->getName() %> +

    User 1: <%= user_1->getPublicHex() %>

    +

    User 2: <%= user_2->getPublicHex() %>

    +
    +
    <%= user_group2->getModel()->getName() %> +

    User 3: <%= user_3->getPublicHex() %>

    +
    +

    Time: <%= time2.string() %> +

  • +
  • +

    2. Send a add-member transaction to hedera topic with one signature (first user)

    + <% + time2.reset(); + if(!steps[0]) { %> +

    skipped

    + <% } else { + auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); + transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + transaction1->sign(user_1); + auto transaction1_json = transaction1->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction1_json) %>

    + <% } %> +

    Time: <%= time2.string() %> +

  • +
  • +

    3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

    + <% + time2.reset(); + if(!steps[1]) { %> +

    skipped

    + <% } else { + auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); + transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); + transaction2->sign(user_2); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction2->sign(user_1); + auto transaction2_json = transaction2->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction2_json) %>

    + <% } %> +

    Time: <%= time2.string() %> +

  • +
  • +

    4. Send a creation transaction to second user, signed by first user

    + <% + time2.reset(); + if(!steps[2]) { %> +

    skipped

    + <% } else { + auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction3->sign(user_1); + auto transaction3_json = transaction3->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction3_json) %>

    + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    5. Send a transfer transaction from second user to first user signed by second user

    + <% + time2.reset(); + if(!steps[3]) { %> +

    skipped

    + <% } else { + auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); + auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction4[0]->sign(user_2); + auto transaction4_json = transaction4[0]->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction4_json) %>

    + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    + <% + time2.reset(); + if(!steps[4]) { %> +

    skipped

    + <% } else { + auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); + transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction5->sign(user_3); + auto transaction5_json = transaction5->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %>

    + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    7. Send a cross group transfer from second user to third user signed by second user

    + <% + time2.reset(); + if(!steps[5]) { %> +

    skipped

    + <% } else { + auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); + auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); + if(!transaction6.size()) { + %> + + <% + } else { + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction6[0]->sign(user_2); + auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + auto paired_transaction = transaction6[0]->getPairedTransaction(); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %>

    + <% if(!paired_transaction.isNull()) { + auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); + %>

    <%= DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) %>

    + <% } %> + <% } %> + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions

    + <% if(!steps[6]) { %> +

    skipped

    + <% } else { + Poco::Thread::sleep(hedera_timeout * 1000); + } %> +
  • +
  • +

    9. Ask choosen node for transaction and print result

    + <% time2.reset(); + if(!steps[7] || node_server.isNull()) { + %>

    skipped

    + <% } else { + auto node_server_model = node_server->getModel(); + JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); + Poco::JSON::Object params; + params.set("groupAlias", user_group->getModel()->getAlias()); + params.set("lastKnownSequenceNumber", 0); + auto gn_answear = jsonrpc.request("getTransactions", params); + if(!gn_answear.isNull()) { + std::stringstream ss; + Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); + std::string answear_string = ss.str(); %> + <%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><% + } + } %> +

    Time: <%= time2.string() %>

    +
  • +
+ <% } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { + Profiler time3; + auto node_server_model = node_server->getModel(); + auto user_group = controller::Group::load(node_server_model->getGroupId()); + JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); + Poco::JSON::Object params; + params.set("groupAlias", user_group->getModel()->getAlias()); + params.set("lastKnownSequenceNumber", 0); + auto gn_answear = jsonrpc.request("getTransactions", params); + if(!gn_answear.isNull()) { + std::stringstream ss; + Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); + std::string answear_string = ss.str();%> + <%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><% + } + %> +

Time: <%= time3.string() %>

+ <% } %> + +
+ +<%@ include file="footer.cpsp" %> From f4a67b476d2d20854fc38591170ce9e594d84261 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Wed, 3 Mar 2021 14:47:34 +0100 Subject: [PATCH 183/195] add result json to gradido transactions --- src/cpp/lib/NotificationList.h | 1 + src/cpp/model/gradido/Transaction.cpp | 45 ++++++++++++++------ src/cpp/model/hedera/TransactionId.cpp | 47 ++++++++++++++++++++ src/cpp/model/hedera/TransactionId.h | 44 +++++++++++++++++++ src/cpp/model/table/PendingTask.cpp | 59 ++++++++++++++++++++++++++ src/cpp/model/table/PendingTask.h | 5 +++ 6 files changed, 188 insertions(+), 13 deletions(-) create mode 100644 src/cpp/model/hedera/TransactionId.cpp create mode 100644 src/cpp/model/hedera/TransactionId.h diff --git a/src/cpp/lib/NotificationList.h b/src/cpp/lib/NotificationList.h index a3b2edcf1..e343218bb 100644 --- a/src/cpp/lib/NotificationList.h +++ b/src/cpp/lib/NotificationList.h @@ -45,6 +45,7 @@ public: void printErrors(); std::string getErrorsHtml(); std::string getErrorsHtmlNewFormat(); + std::vector getErrorsArray(); void sendErrorsAsEmail(std::string rawHtml = ""); diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index 5fb937688..0bbaf0ec1 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -10,8 +10,10 @@ #include "../../controller/HederaRequest.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" #include "../hedera/Transaction.h" +#include "../hedera/TransactionId.h" #include "../../tasks/HederaTask.h" @@ -413,7 +415,8 @@ namespace model { transaction->sign(user); // dirty hack because gn crashes if its get transactions out of order mPairedTransaction = transaction; - Poco::Thread::sleep(1000); + // removed because now using only one hedera node + //Poco::Thread::sleep(1000); } else { addError(new Error(function_name, "Error creating outbound transaction")); @@ -533,11 +536,11 @@ namespace model { || TRANSACTION_VALID_MISSING_PARAM == result || TRANSCATION_VALID_INVALID_PUBKEY == result || TRANSACTION_VALID_INVALID_SIGN == result) { addError(new ParamError(function_name, "code error", TransactionValidationToString(result))); - sendErrorsAsEmail(); + //sendErrorsAsEmail(); } else if (mTransactionBody->isGroupMemberUpdate()) { addError(new ParamError(function_name, "validation return: ", TransactionValidationToString(result))); - sendErrorsAsEmail(); + //sendErrorsAsEmail(); } else { @@ -572,7 +575,7 @@ namespace model { error_name = t->gettext_str("Unknown Error"); error_description = t->gettext_str("Admin gets an E-Mail"); addError(new ParamError(function_name, "unknown error", TransactionValidationToString(result))); - sendErrorsAsEmail(); + //sendErrorsAsEmail(); } auto pt = PendingTasksManager::getInstance(); @@ -642,7 +645,7 @@ namespace model { consensus_submit_message.setMessage(json_message); } else { - sendErrorsAsEmail(); + //sendErrorsAsEmail(); return -7; } @@ -657,6 +660,7 @@ namespace model { auto hedera_transaction_body = hedera_operator_account->createTransactionBody(); hedera_transaction_body->setConsensusSubmitMessage(consensus_submit_message); model::hedera::Transaction hedera_transaction; + hedera_transaction.sign(crypto_key->getKeyPair(), std::move(hedera_transaction_body)); HederaRequest hedera_request; @@ -666,7 +670,7 @@ namespace model { { addError(new Error(function_name, "error send transaction to hedera")); getErrors(&hedera_request); - sendErrorsAsEmail(); + //sendErrorsAsEmail(); return -2; } else { @@ -686,10 +690,19 @@ namespace model { // simply assume if transaction was sended to hedera without error, it was also accepted from gradido node // TODO: later check, but now I haven't any way to communicate with the gradido node mTransactionBody->getTransactionBase()->transactionAccepted(getUser()); + auto transaction_model = getModel(); + transaction_model->setFinished(Poco::DateTime()); + Poco::JSON::Object::Ptr result = new Poco::JSON::Object; + model::hedera::TransactionId transaction_id(hedera_task->getTransactionId()); + result->set("state", "success"); + result->set("transactionId", transaction_id.convertToJSON()); + + transaction_model->setResultJson(result); + Profiler timer; + transaction_model->updateFinishedAndResult(); + printf("time for update 2 fields in db: %s\n", timer.string().data()); + // trigger community server update in 5 seconds - Poco::DateTime now; - std::string now_string = Poco::DateTimeFormatter::format(now, "%f.%m.%Y %H:%M:%S"); - //printf("[%s] trigger community server update in 5 second, now: %s\n", function_name, now_string.data()); CronManager::getInstance()->scheduleUpdateRun(Poco::Timespan(5, 0)); return 1; } @@ -700,7 +713,7 @@ namespace model { else { addError(new ParamError(function_name, "hedera crypto key not found for paying for consensus submit message! NetworkType: ", network_type)); - sendErrorsAsEmail(); + //sendErrorsAsEmail(); return -3; } } @@ -709,7 +722,7 @@ namespace model { addError(new Error(function_name, "hedera topic id or operator account not found!")); addError(new ParamError(function_name, "topic id: ", topic_id->getModel()->toString())); addError(new ParamError(function_name, "network type: ", network_type)); - sendErrorsAsEmail(); + //sendErrorsAsEmail(); return -4; } return 0; @@ -795,11 +808,17 @@ namespace model { //printf("[SendTransactionTask::run] result: %d\n", result); // delete because of error if (-1 == result) { - mTransaction->deleteFromDB(); + //mTransaction->deleteFromDB(); + Poco::JSON::Object::Ptr errors = new Poco::JSON::Object; + errors->set("errors", mTransaction->getErrorsArray()); + errors->set("state", "error"); + auto model = mTransaction->getModel(); + model->setResultJson(errors); + model->updateFinishedAndResult(); } // delete because succeed, maybe change later if (1 == result) { - mTransaction->deleteFromDB(); + //mTransaction->deleteFromDB(); } return 0; } diff --git a/src/cpp/model/hedera/TransactionId.cpp b/src/cpp/model/hedera/TransactionId.cpp new file mode 100644 index 000000000..df6606af1 --- /dev/null +++ b/src/cpp/model/hedera/TransactionId.cpp @@ -0,0 +1,47 @@ +#include "TransactionId.h" + +#include "../../lib/DataTypeConverter.h" + +namespace model { + namespace hedera { + TransactionId::TransactionId() + : shard(0), realm(0), num(0) + { + + } + + TransactionId::TransactionId(const proto::TransactionID& transaction) + { + auto account_id = transaction.accountid(); + shard = account_id.shardnum(); + realm = account_id.realmnum(); + num = account_id.accountnum(); + mTransactionValidStart = DataTypeConverter::convertFromProtoTimestamp(transaction.transactionvalidstart()); + + } + + TransactionId::TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart) + : shard(shard), realm(realm), num(num), mTransactionValidStart(transactionValidStart) + { + + } + + TransactionId::~TransactionId() + { + + } + + Poco::JSON::Object::Ptr TransactionId::convertToJSON() + { + Poco::JSON::Object::Ptr result = new Poco::JSON::Object; + result->set("transactionValidStart", mTransactionValidStart); + Poco::JSON::Object accountId; + accountId.set("shard", shard); + accountId.set("realm", realm); + accountId.set("num", num); + result->set("accountId", accountId); + return result; + } + + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionId.h b/src/cpp/model/hedera/TransactionId.h new file mode 100644 index 000000000..dcc877271 --- /dev/null +++ b/src/cpp/model/hedera/TransactionId.h @@ -0,0 +1,44 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing hedera transaction +* +*/ + +#include "../../proto/hedera/BasicTypes.pb.h" + +#include "Poco/JSON/Object.h" + +namespace model { + namespace hedera { + class TransactionId + { + public: + TransactionId(); + TransactionId(const proto::TransactionID& transaction); + TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart); + ~TransactionId(); + + Poco::JSON::Object::Ptr convertToJSON(); + + protected: + Poco::Timestamp mTransactionValidStart; + union { + struct { + int shard; + int realm; + int num; + }; + int val[3]; + }; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H \ No newline at end of file diff --git a/src/cpp/model/table/PendingTask.cpp b/src/cpp/model/table/PendingTask.cpp index bce0bb7f6..72fe10a21 100644 --- a/src/cpp/model/table/PendingTask.cpp +++ b/src/cpp/model/table/PendingTask.cpp @@ -1,5 +1,6 @@ #include "PendingTask.h" +#include "Poco/JSON/Parser.h" //#include using namespace Poco::Data::Keywords; @@ -37,6 +38,36 @@ namespace model mRequest.assignRaw((const unsigned char*)serializedProto.data(), serializedProto.size()); } + void PendingTask::setResultJson(Poco::JSON::Object::Ptr result) + { + UNIQUE_LOCK; + std::stringstream ss; + result->stringify(ss); + mResultJsonString = ss.str(); + } + + Poco::JSON::Object::Ptr PendingTask::getResultJson() const + { + std::string temp; + { + SHARED_LOCK; + temp = mResultJsonString; + } + Poco::JSON::Parser parser; + Poco::Dynamic::Var result; + try + { + result = parser.parse(temp); + } + catch (Poco::JSON::JSONException& jsone) + { + return nullptr; + } + + return result.extract(); + + } + bool PendingTask::updateRequest() { Poco::ScopedLock _poco_lock(mWorkMutex); @@ -63,6 +94,34 @@ namespace model return 0; } + bool PendingTask::updateFinishedAndResult() + { + Poco::ScopedLock _poco_lock(mWorkMutex); + SHARED_LOCK; + if (!mID) { + return 0; + } + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement update(session); + + update << "UPDATE " << getTableName() << " SET finished = ?, result_json = ? where id = ?;", + use(mFinished), use(mResultJsonString), use(mID); + + try { + return 1 == update.execute(); + } + catch (Poco::Exception& ex) { + addError(new ParamError(getTableName(), "[updateFinishedAndResult] mysql error by update", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: \n", toString().data())); + } + //printf("data valid: %s\n", toString().data()); + return 0; + } + + + std::string PendingTask::toString() { std::stringstream ss; diff --git a/src/cpp/model/table/PendingTask.h b/src/cpp/model/table/PendingTask.h index 8d94ad7dc..4fa84a73b 100644 --- a/src/cpp/model/table/PendingTask.h +++ b/src/cpp/model/table/PendingTask.h @@ -41,10 +41,13 @@ namespace model { //! \brief update table row with current request bool updateRequest(); + bool updateFinishedAndResult(); + inline int getUserId() const { SHARED_LOCK; return mUserId; } inline int getHederaId() const { SHARED_LOCK; return mHederaId; } inline const std::vector& getRequest() const { SHARED_LOCK; return mRequest.content(); } inline std::string getRequestCopy() const { SHARED_LOCK; return std::string((const char*)mRequest.content().data(), mRequest.content().size()); } + Poco::JSON::Object::Ptr getResultJson() const; inline Poco::DateTime getCreated() const { SHARED_LOCK; return mCreated; } inline TaskType getTaskType() const { SHARED_LOCK; return (TaskType)mTaskTypeId; } inline const char* getTaskTypeString() const { SHARED_LOCK; return typeToString((TaskType)mTaskTypeId); } @@ -54,6 +57,8 @@ namespace model { inline void setUserId(int userId) { UNIQUE_LOCK; mUserId = userId; } inline void setHederaId(int hederaId) { UNIQUE_LOCK; mHederaId = hederaId; } void setRequest(const std::string& serializedProto); + inline void setFinished(Poco::DateTime date) { UNIQUE_LOCK; mFinished = date; } + void setResultJson(Poco::JSON::Object::Ptr result); inline void setTaskType(TaskType type) { UNIQUE_LOCK; mTaskTypeId = type; } inline void setChildPendingTaskId(int childPendingTaskId) {UNIQUE_LOCK; mChildPendingTaskId = childPendingTaskId;} inline void setParentPendingTaskId(int parentPendingTaskId) { UNIQUE_LOCK; mParentPendingTaskId = parentPendingTaskId; } From c1e82dda941a4d2c090259f7a7a55df0d37d4295 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Wed, 3 Mar 2021 14:48:13 +0100 Subject: [PATCH 184/195] change code style --- src/cpp/SingletonManager/EmailManager.cpp | 343 +++++++++++----------- src/cpp/model/Session.cpp | 6 +- 2 files changed, 175 insertions(+), 174 deletions(-) diff --git a/src/cpp/SingletonManager/EmailManager.cpp b/src/cpp/SingletonManager/EmailManager.cpp index 5760c8ee2..41f45b471 100644 --- a/src/cpp/SingletonManager/EmailManager.cpp +++ b/src/cpp/SingletonManager/EmailManager.cpp @@ -1,172 +1,173 @@ -#include "EmailManager.h" -#include "../ServerConfig.h" - -#include "../Crypto/Obfus_array.h" -#include "../Crypto/DRRandom.h" - -#include "../SingletonManager/LanguageManager.h" - -#include "Poco/Net/SecureSMTPClientSession.h" -#include "Poco/Net/SSLException.h" - - -EmailManager::EmailManager() - : Thread("emails", false), mEmailLog(Poco::Logger::get("emailLog")), mInitalized(false), mDisableEmail(false) -{ - - -} - -EmailManager::~EmailManager() -{ - exit(); - -} - -EmailManager* EmailManager::getInstance() -{ - static EmailManager theOne; - return &theOne; -} - -bool EmailManager::init(const Poco::Util::LayeredConfiguration& cfg) -{ - try { - mDisableEmail = cfg.getBool("email.disable", false); - if (!mDisableEmail) { - mEmailAccount.sender = cfg.getString("email.sender"); - mEmailAccount.admin_receiver = cfg.getString("email.admin_receiver"); - mEmailAccount.username = cfg.getString("email.username"); - mEmailAccount.password = cfg.getString("email.password"); - mEmailAccount.url = cfg.getString("email.smtp.url"); - mEmailAccount.port = cfg.getInt("email.smtp.port"); - } - } - catch (Poco::Exception& ex) { - printf("email account not set in config: %s\n", ex.displayText().data()); - return false; - } - Thread::init("emails"); - mInitalized = true; - - DISASM_FALSERET; - ServerConfig::g_ServerKeySeed->put(3, DRRandom::r64()); - - return true; -} - -void EmailManager::addEmail(model::Email* email) { - if (mDisableEmail) { - std::string log_message = "Email should be sended to: "; - auto email_user = email->getUser(); - if (email_user && email_user->getModel()) { - log_message += email_user->getModel()->getNameWithEmailHtml(); - } - else { - log_message += ""; - } - log_message += ", type: "; - log_message += model::Email::emailTypeString(email->getType()); - mEmailLog.log(log_message); - delete email; - return; - } - mPendingEmails.push(email); - condSignal(); -} - -void EmailManager::exit() -{ - model::Email* email = nullptr; - while (mPendingEmails.pop(email)) { - delete email; - } - mInitalized = false; -} - -int EmailManager::ThreadFunction() -{ - // prepare connection to email server - if (ServerConfig::g_disableEmail) return 0; - - if (mPendingEmails.empty()) return 0; - - auto lm = LanguageManager::getInstance(); - - Poco::Net::SecureSMTPClientSession mailClientSession(mEmailAccount.url, mEmailAccount.port); - mailClientSession.login(); - try { - mailClientSession.startTLS(ServerConfig::g_SSL_CLient_Context); - mailClientSession.login(Poco::Net::SMTPClientSession::AUTH_LOGIN, mEmailAccount.username, mEmailAccount.password); - } - catch (Poco::Net::SSLException& ex) { - printf("[PrepareEmailTask] ssl certificate error: %s\nPlease make sure you have cacert.pem (CA/root certificates) next to binary from https://curl.haxx.se/docs/caextract.html\n", ex.displayText().data()); - return -1; - } - - model::Email* email = nullptr; - Poco::AutoPtr catalogs[2]; - - // if email list empty, wait 500ms x time before exit thread and closing connection - int timeoutWaits = 20; - - while (mPendingEmails.pop(email) || timeoutWaits > 0) { - if (email) { - Poco::Net::MailMessage mailMessage; - mailMessage.setSender(mEmailAccount.sender); - Languages lang_code = ServerConfig::g_default_locale; - if (email->getUser()) { - Poco::AutoPtr userModel = email->getUser()->getModel(); - - if (!userModel.isNull()) { - userModel->lock("EmailManager::ThreadFunction"); - lang_code = LanguageManager::languageFromString(userModel->getLanguageKey()); - userModel->unlock(); - if (lang_code > LANG_COUNT) lang_code = ServerConfig::g_default_locale; - } - } - if (catalogs[lang_code].isNull()) { - catalogs[lang_code] = lm->getFreeCatalog(lang_code); - } - if (email->draft(&mailMessage, catalogs[lang_code])) { - - mailClientSession.sendMessage(mailMessage); - // add for debugging - if (email->getUser()) { - //printf("send email to %s\n", user_model->getEmail().data()); - auto user_model = email->getUser()->getModel(); - std::string log_message = "Email sended to: "; - auto email_user = email->getUser(); - if (user_model) { - log_message += email_user->getModel()->getNameWithEmailHtml(); - } - else { - log_message += ""; - } - log_message += ", type: "; - log_message += model::Email::emailTypeString(email->getType()); - mEmailLog.log(log_message); - } - } - else { - // error drafting email, shouldn't happend - printf("[EmailManager::ThreadFunction] Error drafting email\n"); - } - delete email; - email = nullptr; - } - if (mPendingEmails.empty()) { - Poco::Thread::sleep(500); - timeoutWaits--; - } - } - - - - - - - mailClientSession.close(); - - return 0; +#include "EmailManager.h" +#include "../ServerConfig.h" + +#include "../Crypto/Obfus_array.h" +#include "../Crypto/DRRandom.h" + +#include "../SingletonManager/LanguageManager.h" + +#include "Poco/Net/SecureSMTPClientSession.h" +#include "Poco/Net/SSLException.h" + + +EmailManager::EmailManager() + : Thread("emails", false), mEmailLog(Poco::Logger::get("emailLog")), mInitalized(false), mDisableEmail(false) +{ + + +} + +EmailManager::~EmailManager() +{ + exit(); + +} + +EmailManager* EmailManager::getInstance() +{ + static EmailManager theOne; + return &theOne; +} + +bool EmailManager::init(const Poco::Util::LayeredConfiguration& cfg) +{ + try { + mDisableEmail = cfg.getBool("email.disable", false); + if (!mDisableEmail) { + mEmailAccount.sender = cfg.getString("email.sender"); + mEmailAccount.admin_receiver = cfg.getString("email.admin_receiver"); + mEmailAccount.username = cfg.getString("email.username"); + mEmailAccount.password = cfg.getString("email.password"); + mEmailAccount.url = cfg.getString("email.smtp.url"); + mEmailAccount.port = cfg.getInt("email.smtp.port"); + } + } + catch (Poco::Exception& ex) { + printf("email account not set in config: %s\n", ex.displayText().data()); + return false; + } + Thread::init("emails"); + mInitalized = true; + + DISASM_FALSERET; + ServerConfig::g_ServerKeySeed->put(3, DRRandom::r64()); + + return true; +} + +void EmailManager::addEmail(model::Email* email) { + if (mDisableEmail) { + std::string log_message = "Email should be sended to: "; + auto email_user = email->getUser(); + Poco::AutoPtr email_model; + if (email_user) { + email_model = email_user->getModel(); + log_message += email_model->getNameWithEmailHtml(); + } + if (email_model.isNull()) { + log_message += ""; + } + log_message += ", type: "; + log_message += model::Email::emailTypeString(email->getType()); + mEmailLog.log(log_message); + + delete email; + return; + } + mPendingEmails.push(email); + condSignal(); +} + +void EmailManager::exit() +{ + model::Email* email = nullptr; + while (mPendingEmails.pop(email)) { + delete email; + } + mInitalized = false; +} + +int EmailManager::ThreadFunction() +{ + // prepare connection to email server + if (ServerConfig::g_disableEmail) return 0; + + if (mPendingEmails.empty()) return 0; + + auto lm = LanguageManager::getInstance(); + + Poco::Net::SecureSMTPClientSession mailClientSession(mEmailAccount.url, mEmailAccount.port); + mailClientSession.login(); + try { + mailClientSession.startTLS(ServerConfig::g_SSL_CLient_Context); + mailClientSession.login(Poco::Net::SMTPClientSession::AUTH_LOGIN, mEmailAccount.username, mEmailAccount.password); + } + catch (Poco::Net::SSLException& ex) { + printf("[PrepareEmailTask] ssl certificate error: %s\nPlease make sure you have cacert.pem (CA/root certificates) next to binary from https://curl.haxx.se/docs/caextract.html\n", ex.displayText().data()); + return -1; + } + + model::Email* email = nullptr; + Poco::AutoPtr catalogs[2]; + + // if email list empty, wait 500ms x time before exit thread and closing connection + int timeoutWaits = 20; + + while (mPendingEmails.pop(email) || timeoutWaits > 0) { + if (email) { + Poco::Net::MailMessage mailMessage; + mailMessage.setSender(mEmailAccount.sender); + Languages lang_code = ServerConfig::g_default_locale; + auto email_user = email->getUser(); + if (email_user) { + Poco::AutoPtr userModel = email_user->getModel(); + + if (!userModel.isNull()) { + lang_code = LanguageManager::languageFromString(userModel->getLanguageKey()); + if (lang_code > LANG_COUNT) lang_code = ServerConfig::g_default_locale; + } + } + if (catalogs[lang_code].isNull()) { + catalogs[lang_code] = lm->getFreeCatalog(lang_code); + } + if (email->draft(&mailMessage, catalogs[lang_code])) { + + mailClientSession.sendMessage(mailMessage); + // add for debugging + if (email_user) { + //printf("send email to %s\n", user_model->getEmail().data()); + auto user_model = email_user->getModel(); + std::string log_message = "Email sended to: "; + if (user_model) { + log_message += email_user->getModel()->getNameWithEmailHtml(); + } + else { + log_message += ""; + } + log_message += ", type: "; + log_message += model::Email::emailTypeString(email->getType()); + mEmailLog.log(log_message); + } + } + else { + // error drafting email, shouldn't happend + printf("[EmailManager::ThreadFunction] Error drafting email\n"); + } + delete email; + email = nullptr; + } + if (mPendingEmails.empty()) { + Poco::Thread::sleep(500); + timeoutWaits--; + } + } + + + + + + + mailClientSession.close(); + + return 0; } \ No newline at end of file diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index b06d2b14d..934d3bc9a 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -145,8 +145,8 @@ Poco::AutoPtr Session::getEmailVerificationCo bool Session::adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email, int group_id, const std::string &baseUrl) { Profiler usedTime; - - if (mNewUser->getModel()->getRole() != model::table::ROLE_ADMIN) { + auto user_model = mNewUser->getModel(); + if (user_model->getRole() != model::table::ROLE_ADMIN) { addError(new Error(gettext("Benutzer"), gettext("Eingeloggter Benutzer ist kein Admin")), false); return false; } @@ -167,7 +167,7 @@ bool Session::adminCreateUser(const std::string& first_name, const std::string& // check if user with that email already exist - if (mNewUser->getModel()->isExistInDB("email", email)) { + if (user_model->isExistInDB("email", email)) { addError(new Error(gettext("E-Mail"), gettext("Für diese E-Mail Adresse gibt es bereits einen Account")), false); return false; } From 82f39c3add0505d98a9692008370d440b29a48cd Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Wed, 3 Mar 2021 14:49:17 +0100 Subject: [PATCH 185/195] fix deadlock, remove pending tasks if the contain state == "success" in result JSON, check every second --- .../SingletonManager/PendingTasksManager.cpp | 54 ++++++++++++++++--- .../SingletonManager/PendingTasksManager.h | 10 +++- src/cpp/controller/PendingTask.cpp | 4 -- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/cpp/SingletonManager/PendingTasksManager.cpp b/src/cpp/SingletonManager/PendingTasksManager.cpp index 35c28c72b..1f8071908 100644 --- a/src/cpp/SingletonManager/PendingTasksManager.cpp +++ b/src/cpp/SingletonManager/PendingTasksManager.cpp @@ -4,13 +4,17 @@ PendingTasksManager::PendingTasksManager() + : mCheckForFinishedTimer(2000, 2000) { - + //mCheckForFinishedTimer } PendingTasksManager::~PendingTasksManager() { + Poco::ScopedLock _lock(mWorkMutex); + mCheckForFinishedTimer.stop(); + for (auto it = mPendingTasks.begin(); it != mPendingTasks.end(); it++) { delete it->second; } @@ -27,6 +31,9 @@ int PendingTasksManager::load() { // they add them self to Pending Task Manager auto pending_tasks = controller::PendingTask::loadAll(); + Poco::TimerCallback callback(*this, &PendingTasksManager::checkForFinishedTasks); + mCheckForFinishedTimer.start(callback); + return 0; } @@ -138,9 +145,11 @@ std::vector> PendingTasksManager::getTra auto list = map_it->second; for (auto list_it = list->begin(); list_it != list->end(); list_it++) { - auto transaction = dynamic_cast(list_it->get()); - if (transaction->mustSign(user)) { - transactions_to_sign.push_back(*list_it); + if ((*list_it)->getModel()->isGradidoTransaction()) { + auto transaction = dynamic_cast(list_it->get()); + if (transaction->mustSign(user)) { + transactions_to_sign.push_back(*list_it); + } } } } @@ -158,15 +167,45 @@ std::vector> PendingTasksManager::getTran auto list = map_it->second; for (auto list_it = list->begin(); list_it != list->end(); list_it++) { - auto transaction = dynamic_cast(list_it->get()); - if (transaction->needSomeoneToSign(user)) { - transactions_to_sign.push_back(*list_it); + if ((*list_it)->getModel()->isGradidoTransaction()) { + auto transaction = dynamic_cast(list_it->get()); + if (transaction->needSomeoneToSign(user)) { + transactions_to_sign.push_back(*list_it); + } } } } return transactions_to_sign; } +void PendingTasksManager::checkForFinishedTasks(Poco::Timer& timer) +{ + Poco::ScopedLock _lock(mWorkMutex); + + for (auto map_it = mPendingTasks.begin(); map_it != mPendingTasks.end(); map_it++) + { + auto list = map_it->second; + for (auto list_it = list->begin(); list_it != list->end(); list_it++) + { + if ((*list_it)->getModel()->isGradidoTransaction()) { + auto transaction = dynamic_cast(list_it->get()); + auto json = transaction->getModel()->getResultJson(); + bool removeIt = false; + if (!json.isNull()) { + if (json->get("state").toString() == "success") { + removeIt = true; + } + } + if (removeIt) { + transaction->deleteFromDB(); + list_it = list->erase(list_it); + if (!list->size()) break; + } + } + } + } +} + Poco::AutoPtr PendingTasksManager::getPendingTask(int pendingTaskId) { Poco::ScopedLock _lock(mWorkMutex); @@ -183,6 +222,7 @@ Poco::AutoPtr PendingTasksManager::getPendingTask(int p return nullptr; } + void PendingTasksManager::reportErrorToCommunityServer(Poco::AutoPtr task, std::string error, std::string errorDetails) { // TODO: choose user specific server diff --git a/src/cpp/SingletonManager/PendingTasksManager.h b/src/cpp/SingletonManager/PendingTasksManager.h index cec9bc5b6..8444f32ea 100644 --- a/src/cpp/SingletonManager/PendingTasksManager.h +++ b/src/cpp/SingletonManager/PendingTasksManager.h @@ -17,8 +17,11 @@ #include "../controller/User.h" #include "../model/gradido/Transaction.h" -class PendingTasksManager: public UniLib::lib::MultithreadContainer +class UserUpdateGroupPage; + +class PendingTasksManager: protected UniLib::lib::MultithreadContainer { + friend UserUpdateGroupPage; public: typedef std::list> PendingTaskList; @@ -34,6 +37,9 @@ public: int addTask(Poco::AutoPtr task); bool removeTask(Poco::AutoPtr task); + //! check if tasks can be removed + void checkForFinishedTasks(Poco::Timer& timer); + //! by calling this, important is to call lock to prevent vanishing the list while working with it, //! and unlock afterwards //! \return list or nullptr if no list for user exist @@ -49,7 +55,7 @@ public: protected: PendingTasksManager(); - + Poco::Timer mCheckForFinishedTimer; std::map mPendingTasks; diff --git a/src/cpp/controller/PendingTask.cpp b/src/cpp/controller/PendingTask.cpp index e36fdcc7d..2b991b580 100644 --- a/src/cpp/controller/PendingTask.cpp +++ b/src/cpp/controller/PendingTask.cpp @@ -87,10 +87,6 @@ namespace controller { { Poco::ScopedLock _lock(mWorkMutex); auto result = mDBModel->deleteFromDB(); - if (result) { - - PendingTasksManager::getInstance()->removeTask(Poco::AutoPtr(this, true)); - } return result; } From e49802c9bcc4bed8f1268e723eee850fb7bf4f58 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Wed, 3 Mar 2021 14:50:21 +0100 Subject: [PATCH 186/195] fix naming (differ from community server), enable back request transactions from gn --- src/cpp/JSONInterface/JsonGetLogin.cpp | 6 +++--- src/cpp/SingletonManager/CronManager.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpp/JSONInterface/JsonGetLogin.cpp b/src/cpp/JSONInterface/JsonGetLogin.cpp index cf97302c2..65638bf37 100644 --- a/src/cpp/JSONInterface/JsonGetLogin.cpp +++ b/src/cpp/JSONInterface/JsonGetLogin.cpp @@ -76,17 +76,17 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params) int pending = 0; auto user_must_sign = pt->getTransactionsUserMustSign(userNew); pending = user_must_sign.size(); - result->set("Transaction.pending", pending); + result->set("Transactions.pending", pending); auto some_must_sign = pt->getTransactionSomeoneMustSign(userNew); //pending = some_must_sign.size(); - result->set("Transaction.can_signed", some_must_sign.size()); + result->set("Transactions.can_signed", some_must_sign.size()); auto executing = observer->getTaskCount(userModel->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION); if (executing < 0) { executing = 0; } - result->set("Transaction.executing", executing); + result->set("Transactions.executing", executing); //printf("pending: %d\n", session->getProcessingTransactionCount()); //std::string user_string = userModel->toString(); //printf("[JsonGetLogin] %s\n", user_string.data()); diff --git a/src/cpp/SingletonManager/CronManager.cpp b/src/cpp/SingletonManager/CronManager.cpp index f3eae73a6..893cb7040 100644 --- a/src/cpp/SingletonManager/CronManager.cpp +++ b/src/cpp/SingletonManager/CronManager.cpp @@ -193,8 +193,8 @@ int PingServerTask::run() std::string url_port = mNodeServer->getModel()->getUrlWithPort(); printf("%s [PingServerTask::run] call update for %s\n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data(), url_port.data()); - //auto json_request = mNodeServer->createJsonRequest(); - //json_request.request("updateReadNode"); + auto json_request = mNodeServer->createJsonRequest(); + json_request.request("updateReadNode"); } return 0; } \ No newline at end of file From d6b59d5dfdee6fd36a1084dc6c4e97497a6e75dc Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Mar 2021 17:34:47 +0100 Subject: [PATCH 187/195] take updates from stage1 for allow vue-client connecting --- src/cpp/Gradido_LoginServer.cpp | 5 +- src/cpp/JSONInterface/JsonCreateUser.cpp | 12 +++-- src/cpp/JSONInterface/JsonGetLogin.cpp | 49 +++---------------- src/cpp/JSONInterface/JsonRequestHandler.cpp | 5 +- .../JsonRequestHandlerFactory.cpp | 15 ++++++ src/cpp/JSONInterface/JsonUnsecureLogin.cpp | 3 +- src/cpp/ServerConfig.cpp | 19 +++++++ src/cpp/ServerConfig.h | 4 ++ 8 files changed, 57 insertions(+), 55 deletions(-) diff --git a/src/cpp/Gradido_LoginServer.cpp b/src/cpp/Gradido_LoginServer.cpp index 8e6040337..5d3f09f03 100644 --- a/src/cpp/Gradido_LoginServer.cpp +++ b/src/cpp/Gradido_LoginServer.cpp @@ -256,8 +256,8 @@ int Gradido_LoginServer::main(const std::vector& args) // load pending tasks not finished in last session PendingTasksManager::getInstance()->load(); - - CronManager::getInstance()->init(); + int php_server_ping = config().getInt("phpServer.ping", 600000); + CronManager::getInstance()->init(php_server_ping); printf("[Gradido_LoginServer::main] started in %s\n", usedTime.string().data()); // wait for CTRL-C or kill @@ -270,7 +270,6 @@ int Gradido_LoginServer::main(const std::vector& args) // Stop the json server json_srv.stop(); - ServerConfig::unload(); Poco::Net::uninitializeSSL(); // Optional: Delete all global objects allocated by libprotobuf. diff --git a/src/cpp/JSONInterface/JsonCreateUser.cpp b/src/cpp/JSONInterface/JsonCreateUser.cpp index d21874aaa..f0a6ee7e9 100644 --- a/src/cpp/JSONInterface/JsonCreateUser.cpp +++ b/src/cpp/JSONInterface/JsonCreateUser.cpp @@ -18,6 +18,7 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) bool login_after_register = false; int emailType; int group_id; + auto em = EmailManager::getInstance(); auto sm = SessionManager::getInstance(); @@ -35,6 +36,7 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) paramJsonObject->get("last_name").convert(last_name); paramJsonObject->get("emailType").convert(emailType); paramJsonObject->get("group_id").convert(group_id); + if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) { paramJsonObject->get("password").convert(password); } @@ -52,15 +54,15 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) auto user = controller::User::create(); if (user->load(email) > 0) { - // return customStateError("exist", "user already exist"); - Poco::JSON::Object* result = new Poco::JSON::Object; + /*Poco::JSON::Object* result = new Poco::JSON::Object; result->set("state", "exist"); result->set("msg", "user already exist"); - return result; + return result;*/ + return customStateError("exist", "user already exist"); } if (password.size()) { - ErrorList errors; + NotificationList errors; if (!sm->checkPwdValidation(password, &errors)) { Poco::JSON::Object* result = new Poco::JSON::Object; result->set("state", "error"); @@ -91,7 +93,7 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params) UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(user, password); create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); } - + auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); auto emailOptInModel = emailOptIn->getModel(); if (!emailOptInModel->insertIntoDB(false)) { diff --git a/src/cpp/JSONInterface/JsonGetLogin.cpp b/src/cpp/JSONInterface/JsonGetLogin.cpp index 65638bf37..f85a05765 100644 --- a/src/cpp/JSONInterface/JsonGetLogin.cpp +++ b/src/cpp/JSONInterface/JsonGetLogin.cpp @@ -16,50 +16,15 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params) auto pt = PendingTasksManager::getInstance(); auto observer = SingletonTaskObserver::getInstance(); - if (params.isStruct()) { - session_id = params["session_id"]; - //std::string miau = params["miau"]; - } - else if (params.isVector()) { - try { - const Poco::URI::QueryParameters queryParams = params.extract(); - for (auto it = queryParams.begin(); it != queryParams.end(); it++) { - if (it->first == "session_id") { - auto numberParseResult = DataTypeConverter::strToInt(it->second, session_id); - if (DataTypeConverter::NUMBER_PARSE_OKAY != numberParseResult) { - return stateError("error parsing session_id", DataTypeConverter::numberParseStateToString(numberParseResult)); - } - break; - } - } - //auto var = params[0]; - } - catch (Poco::Exception& ex) { - return stateError("error parsing query params, Poco Error", ex.displayText()); - } - } - - if (!session_id) { - return stateError("empty session id"); - } - - auto session = sm->getSession(session_id); - if (!session) { - return customStateError("not found", "session not found"); - } - - auto userNew = session->getNewUser(); - //auto user = session->getUser(); - if (userNew.isNull()) { - return customStateError("not found", "Session didn't contain user"); - } - auto userModel = userNew->getModel(); - if(userModel.isNull()) { - return customStateError("not found", "User is empty"); + auto session_check_result = checkAndLoadSession(params, true); + if (session_check_result) { + return session_check_result; } + Poco::JSON::Object* result = new Poco::JSON::Object; result->set("state", "success"); - result->set("clientIP", session->getClientIp().toString()); + //result->set("clientIP", mSession->getClientIp().toString()); + auto userNew = mSession->getNewUser(); try { result->set("user", userNew->getJson()); } @@ -82,7 +47,7 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params) //pending = some_must_sign.size(); result->set("Transactions.can_signed", some_must_sign.size()); - auto executing = observer->getTaskCount(userModel->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION); + auto executing = observer->getTaskCount(userNew->getModel()->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION); if (executing < 0) { executing = 0; } diff --git a/src/cpp/JSONInterface/JsonRequestHandler.cpp b/src/cpp/JSONInterface/JsonRequestHandler.cpp index 3fedcd01e..9453434de 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandler.cpp @@ -29,7 +29,6 @@ JsonRequestHandler::JsonRequestHandler(Session* session) void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) { - response.setChunkedTransferEncoding(false); response.setContentType("application/json"); if (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_CORS_ALL) { @@ -72,12 +71,12 @@ void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Po json_result->get("session_id").convert(session_id); } catch (Poco::Exception& e) { - ErrorList erros; + NotificationList erros; erros.addError(new Error("json request", "invalid session_id")); erros.sendErrorsAsEmail(); } if (session_id) { - auto session = SessionManager::getInstance()->getSession("session_id"); + auto session = SessionManager::getInstance()->getSession(session_id); response.addCookie(session->getLoginCookie()); } } diff --git a/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp b/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp index 2fd76c4b9..1ec87d9f5 100644 --- a/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp @@ -14,8 +14,10 @@ #include "JsonTransaction.h" #include "JsonGetRunningUserTasks.h" #include "JsonGetUsers.h" +#include "JsonLogout.h" #include "JsonNetworkInfos.h" #include "JsonGetUserInfos.h" +#include "JsonUnsecureLogin.h" #include "JsonUpdateUserInfos.h" #include "JsonUnsecureLogin.h" #include "JsonLogout.h" @@ -63,6 +65,12 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c s = sm->getSession(session_id); } + auto client_host = request.clientAddress().host(); + //auto client_ip = request.clientAddress(); + // X-Real-IP forwarded ip from nginx config + auto client_host_string = request.get("X-Real-IP", client_host.toString()); + client_host = Poco::Net::IPAddress(client_host_string); + if (url_first_part == "/login") { return new JsonGetLogin; } @@ -107,6 +115,9 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c requestHandler->setSession(s); return requestHandler; } + else if (url_first_part == "/unsecureLogin" && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) { + return new JsonUnsecureLogin(client_host); + } else if (url_first_part == "/appLogin") { return new JsonAppLogin; } @@ -115,5 +126,9 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c sm->releaseSession(s); } } + else if (url_first_part == "/logout") { + return new JsonLogout(client_host); + } + return new JsonUnknown; } diff --git a/src/cpp/JSONInterface/JsonUnsecureLogin.cpp b/src/cpp/JSONInterface/JsonUnsecureLogin.cpp index 18080cfa6..401f46e41 100644 --- a/src/cpp/JSONInterface/JsonUnsecureLogin.cpp +++ b/src/cpp/JSONInterface/JsonUnsecureLogin.cpp @@ -52,7 +52,7 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params) return stateError("user with email not found", email); } - ErrorList pwd_errors; + NotificationList pwd_errors; Poco::JSON::Object* result = new Poco::JSON::Object; if (!password.size() || !sm->checkPwdValidation(password, &pwd_errors)) { @@ -110,5 +110,4 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params) sm->releaseSession(session); return result; - } \ No newline at end of file diff --git a/src/cpp/ServerConfig.cpp b/src/cpp/ServerConfig.cpp index ba8d5f784..5aaf65edc 100644 --- a/src/cpp/ServerConfig.cpp +++ b/src/cpp/ServerConfig.cpp @@ -59,8 +59,10 @@ namespace ServerConfig { ServerSetupType g_ServerSetupType = SERVER_TYPE_PRODUCTION; std::string g_gRPCRelayServerFullURL; MemoryBin* g_CryptoAppSecret = nullptr; + AllowUnsecure g_AllowUnsecureFlags = NOT_UNSECURE; HederaConsensusMessageFormat g_ConsensusMessageFormat = HEDERA_CONSENSUS_FORMAT_BINARY; HederaNetworkType g_HederaNetworkType = HEDERA_TESTNET; + Poco::Timespan g_HederaDefaultTimeout; #ifdef __linux__ #include @@ -262,6 +264,23 @@ namespace ServerConfig { } //g_CryptoAppSecret + // unsecure flags + //g_AllowUnsecureFlags + if (cfg.getInt("unsecure.allow_passwort_via_json_request", 0) == 1) { + g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_PASSWORD_REQUESTS); + } + if (cfg.getInt("unsecure.allow_auto_sign_transactions", 0) == 1) { + g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_AUTO_SIGN_TRANSACTIONS); + } + if (cfg.getInt("unsecure.allow_cors_all", 0) == 1) { + g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_CORS_ALL); + } + if (cfg.getInt("unsecure.allow_all_passwords", 0) == 1) { + g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_ALLOW_ALL_PASSWORDS); + } + + g_HederaDefaultTimeout = cfg.getInt("hedera.default_timeout", 5); + g_gRPCRelayServerFullURL = cfg.getString("grpc.server", ""); // unsecure flags diff --git a/src/cpp/ServerConfig.h b/src/cpp/ServerConfig.h index 4a0cbec7d..9d48521fa 100644 --- a/src/cpp/ServerConfig.h +++ b/src/cpp/ServerConfig.h @@ -61,6 +61,8 @@ namespace ServerConfig { HEDERA_UNKNOWN }; + + extern Mnemonic g_Mnemonic_WordLists[MNEMONIC_MAX]; @@ -90,6 +92,8 @@ namespace ServerConfig { extern AllowUnsecure g_AllowUnsecureFlags; extern HederaConsensusMessageFormat g_ConsensusMessageFormat; extern HederaNetworkType g_HederaNetworkType; + extern Poco::Timespan g_HederaDefaultTimeout; + bool loadMnemonicWordLists(); bool initServerCrypto(const Poco::Util::LayeredConfiguration& cfg); From 32a2b4d85108cbb701b4a3068142edc9312e91d2 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 4 Mar 2021 18:00:19 +0100 Subject: [PATCH 188/195] using password validation in login only for saving cpu time (fake sleep by invalid passwords instead of make hash calculation with argon2) --- src/cpp/model/Session.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 934d3bc9a..0aa1ae08b 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -736,6 +736,8 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor { static const char* functionName = "Session::loadUser"; auto observer = SingletonTaskObserver::getInstance(); + auto sm = SessionManager::getInstance(); + if (email != "") { if (observer->getTaskCount(email, TASK_OBSERVER_PASSWORD_CREATION) > 0) { return USER_PASSWORD_ENCRYPTION_IN_PROCESS; @@ -765,6 +767,14 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor return USER_DISABLED; } if (mNewUser->getUserState() >= USER_LOADED_FROM_DB) { + + NotificationList pwd_errors; + if (!sm->checkPwdValidation(password, &pwd_errors)) + { + Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime); + return USER_PASSWORD_INCORRECT; + } + int loginResult = mNewUser->login(password); int exitCount = 0; if (loginResult == -3) From 4f8bbb1a3102839eaa9d30cdd77247d33fd40449 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 9 Mar 2021 16:13:48 +0100 Subject: [PATCH 189/195] not using shared libs any more because it don't work --- conanfile.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/conanfile.txt b/conanfile.txt index bececd85e..ae0fcd97b 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -8,11 +8,6 @@ gtest/1.8.1@bincrafters/stable cmake [options] -Poco:shared=True Poco:enable_data_sqlite=False Poco:enable_mongodb=False Poco:enable_redis=False -boost:shared=True - -[generators] -virtualrunenv From d14de915b2e388aacdd69cab48fdc6c930d467e6 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 9 Mar 2021 16:14:27 +0100 Subject: [PATCH 190/195] add docker file, updated version from stage1 --- Dockerfile.debug | 244 ++++++++++++++++++++++------------------------- 1 file changed, 113 insertions(+), 131 deletions(-) diff --git a/Dockerfile.debug b/Dockerfile.debug index 0c7c741d5..6fcea2cef 100644 --- a/Dockerfile.debug +++ b/Dockerfile.debug @@ -1,132 +1,114 @@ -######################################################################################################### -# Build protoc -######################################################################################################### -FROM gcc:7.5 as protoc_build -RUN git clone --recurse-submodules https://github.com/protocolbuffers/protobuf.git -WORKDIR /protobuf - -RUN git checkout v3.9.1 -RUN ./autogen.sh -RUN ./configure --enable-static=yes -RUN make -j$(grep processor /proc/cpuinfo | wc -l) -RUN make check - -CMD ["./protobuf"] - -######################################################################################################### -# debug build preparation -######################################################################################################### - -From conanio/gcc7 as debug_preparation - -ENV DOCKER_WORKDIR="/code" - -USER root - -COPY --from=protoc_build /protobuf/src/.libs/protoc /usr/bin/ -COPY --from=protoc_build /protobuf/src/.libs/libprotobuf.so.20.0.1 /usr/lib/libprotobuf.so.20 -COPY --from=protoc_build /protobuf/src/.libs/libprotoc.so.20.0.1 /usr/lib/libprotoc.so.20 -COPY --from=protoc_build /protobuf/src/google/protobuf/*.proto /usr/include/google/protobuf/ -COPY --from=protoc_build /protobuf/src/google/protobuf/*.h /usr/include/google/protobuf/ - -#VOLUME /root/.conan - -RUN mkdir -p ${DOCKER_WORKDIR} -WORKDIR ${DOCKER_WORKDIR} - -COPY ./dependencies ./dependencies -COPY ./conanfile.txt ./conanfile.txt - -RUN ls -la -RUN cd dependencies/iroha-ed25519 && \ - ls -la && \ - mkdir build && \ - cd build && \ - cmake .. -DCMAKE_BUILD_TYPE=Debug -DEDIMPL=ref10 -DHASH=sha2_sphlib -DRANDOM=bcryptgen -DBUILD=STATIC && \ - make -j$(grep processor /proc/cpuinfo | wc -l) - -RUN cd dependencies/mariadb-connector-c && \ - mkdir build && \ - cd build && \ - cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_SSL=OFF .. - - -#RUN chmod +x compile_proto.sh -#RUN chmod +x compile_pot.sh -#RUN ls -la -#RUN ./compile_pot.sh -#RUN ./compile_proto.sh -RUN mkdir build && \ - cd build && \ - conan install .. --build=missing -s build_type=Debug - - - -######################################################################################################### -# Build debug -######################################################################################################### -From debug_preparation as debug - -ENV DOCKER_WORKDIR="/code" - -USER root -#VOLUME /root/.conan - -RUN apt-get update && \ - apt-get install -y --no-install-recommends gdb && \ - apt-get autoclean && \ - apt-get autoremove && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -#COPY --from=protoc_build /protobuf/src/.libs/libprotobuf.so.20.0.1 /usr/lib/libprotobuf.so.20 -#COPY --from=protoc_build /protobuf/src/google/protobuf/*.h /usr/include/google/protobuf/ - - -#COPY --from=debug_preparation /code /code -#COPY --from=debug_preparation /home/conan /home/conan -#RUN ls -la /home/conan/.conan -COPY . . -WORKDIR ${DOCKER_WORKDIR} - -#RUN ls -la -#RUN cat build/conanbuildinfo.cmake -RUN chmod +x compile_proto.sh -RUN chmod +x compile_pot.sh -#RUN ls -la -RUN ./compile_pot.sh -RUN ./compile_proto.sh -RUN cd build && \ - cmake -DCMAKE_BUILD_TYPE=Debug .. && \ - make -j$(grep processor /proc/cpuinfo | wc -l) - - -######################################################################################################### -# run debug -######################################################################################################### -FROM ubuntu:latest as login_server_debug - -WORKDIR "/usr/bin" - -#RUN apt-get update && \ -# apt-get install -y --no-install-recommends gdb && \ -# apt-get autoclean && \ -# apt-get autoremove && \ -# apt-get clean && \ -# rm -rf /var/lib/apt/lists/* - -VOLUME /var/log/grd_login - -COPY --from=debug /code/build/bin/Gradido_LoginServer /usr/bin/ -COPY --from=debug /code/build/lib/libmariadb.so.3 /usr/lib/ -#COPY start_after_mysql.sh . -RUN chmod +x /usr/bin/Gradido_LoginServer -EXPOSE 1200 -EXPOSE 1201 -#ENTRYPOINT ["/usr/bin/Gradido_LoginServer"] -# Wait on mariadb to started -#CMD ["sleep 5", "/usr/bin/Gradido_LoginServer"] -#RUN chmod +x ./start_after_mysql.sh -#ENTRYPOINT ["/usr/bin/Gradido_LoginServer"] -#CMD gdb -ex=r Gradido_LoginServer +######################################################################################################### +# debug build preparation +######################################################################################################### + +From conanio/gcc9 as build_debug_preparation +USER root +#RUN apt-get update && \ +# apt-get install -y --no-install-recommends gcc g++ && \ +# apt-get autoclean && \ +# apt-get autoremove && \ +# apt-get clean && \ +# rm -rf /var/lib/apt/lists/* + +ENV DOCKER_WORKDIR="/code" + + +#VOLUME /root/.conan + +RUN mkdir -p ${DOCKER_WORKDIR} +WORKDIR ${DOCKER_WORKDIR} + +COPY ./dependencies ./dependencies +COPY ./conanfile.txt ./conanfile.txt + +RUN cd dependencies/mariadb-connector-c && \ + mkdir build && \ + cd build && \ + cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_SSL=OFF .. + + +RUN mkdir build && \ + cd build && \ + conan install .. --build=missing -s build_type=Debug + +######################################################################################################### +# debug build proto and grpc +######################################################################################################### +From build_debug_preparation as proto_grpc + +ENV DOCKER_WORKDIR="/code" +WORKDIR ${DOCKER_WORKDIR} + +COPY ./CMakeLists.txt . +RUN cd build && \ + cmake -DCMAKE_BUILD_TYPE=Debug .. && \ + make -j${CPU_COUNT} protoc grpc_cpp_plugin + +######################################################################################################### +# parse proto and gettext +######################################################################################################### +From proto_grpc as proto_parse + +ENV DOCKER_WORKDIR="/code" +WORKDIR ${DOCKER_WORKDIR} + +RUN mkdir src && \ + cd src && \ + mkdir cpp +COPY ./src/proto ./src/proto +COPY ./unix_parse_proto.sh . + +RUN chmod +x unix_parse_proto.sh && \ + ./unix_parse_proto.sh + + +######################################################################################################### +# Build debug +######################################################################################################### +From proto_parse as build_debug + +ENV DOCKER_WORKDIR="/code" + +USER root +WORKDIR ${DOCKER_WORKDIR} + +COPY ./src/cpp ./src/cpp +COPY ./src/LOCALE ./src/LOCALE +COPY ./compile_pot.sh . +COPY ./files_to_translate.txt . + +RUN chmod +x compile_pot.sh && \ + ./compile_pot.sh + +RUN cd build && \ + cmake -DCMAKE_BUILD_TYPE=Debug .. && \ + make -j$(nproc) + +CMD bash + +######################################################################################################### +# run debug +######################################################################################################### +FROM ubuntu:latest as login_server_debug + +WORKDIR "/usr/bin" + +#RUN apt-get update && \ +# apt-get install -y --no-install-recommends gdb && \ +# apt-get autoclean && \ +# apt-get autoremove && \ +# apt-get clean && \ +# rm -rf /var/lib/apt/lists/* + +VOLUME /var/log/grd_login + +COPY --from=build_debug /code/build/bin/Gradido_LoginServer /usr/bin/ +COPY --from=build_debug /code/build/lib/libmariadb.so.3 /usr/lib/ +#COPY --from=build_debug /code/build/lib/libPocoNetSSLd.so.64 /usr/lib/libPocoNetSSLd.so.64 +RUN chmod +x /usr/bin/Gradido_LoginServer +EXPOSE 1200 +EXPOSE 1201 + +#CMD gdb -ex=r Gradido_LoginServer CMD Gradido_LoginServer \ No newline at end of file From a4d1b938fac43ca1afc8b85fd35ade503a47594b Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 9 Mar 2021 16:50:09 +0100 Subject: [PATCH 191/195] add sql script for filling login-server db with neccessary data to work with hedera testnet --- .gitignore | 1 + .../insert/setup_hedera_group.sql | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 skeema/gradido_login/insert/setup_hedera_group.sql diff --git a/.gitignore b/.gitignore index 788c702ad..dd7d9573a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ src/cpsp/*.h src/cpsp/*.cpp src/cpp/proto/ build*/ +/skeema/gradido_login/insert/crypto_key.sql diff --git a/skeema/gradido_login/insert/setup_hedera_group.sql b/skeema/gradido_login/insert/setup_hedera_group.sql new file mode 100644 index 000000000..813f523f7 --- /dev/null +++ b/skeema/gradido_login/insert/setup_hedera_group.sql @@ -0,0 +1,19 @@ +INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES +(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'); + +INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES +(1, 0, 0, 3), +(2, 0, 0, 3327), +(3, 0, 0, 413151); + +INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES +(1, 1, 2, 1, 1000000000000, 1, '2021-01-07 10:22:52'); + +INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `home`, `description`) VALUES +(1, 'docker_stage2', 'docker stage2 gradido group', 'localhost', '/', 'gradido test group for docker and stage2'); + +INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `running_hash`, `running_hash_version`, `updated`) VALUES +(1, 2, 'docker_stage2', 2, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34'); + + + From f7f979507aa1b30e927e213422b08a8494a7e8a3 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 13 Mar 2021 14:20:38 +0100 Subject: [PATCH 192/195] fix missing module urls and errors in CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7930a31e0..ffb1b4e6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ set(WITH_SSL OFF) add_subdirectory("dependencies/mariadb-connector-c") set(DEP_PATH "dependencies") -#set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") +set(MARIADB_CONNECTOR_PATH "${DEP_PATH}/mariadb-connector-c/build/libmariadb") set(GRPC_PATH "${DEP_PATH}/grpc/build") set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types") From 65d280e199bde585d48e23430911d0e4811589f6 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 13 Mar 2021 15:14:30 +0100 Subject: [PATCH 193/195] update db to insert hedera stuff --- skeema/gradido_login/insert/setup_hedera_group.sql | 12 ++++++------ skeema/gradido_login/users.sql | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/skeema/gradido_login/insert/setup_hedera_group.sql b/skeema/gradido_login/insert/setup_hedera_group.sql index 813f523f7..8dd601b97 100644 --- a/skeema/gradido_login/insert/setup_hedera_group.sql +++ b/skeema/gradido_login/insert/setup_hedera_group.sql @@ -1,19 +1,19 @@ -INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES -(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'); +INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `home`, `description`) VALUES +(1, 'dockerStage2', 'docker stage2 gradido group', 'localhost', '/', 'gradido test group for docker and stage2'); INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES (1, 0, 0, 3), (2, 0, 0, 3327), (3, 0, 0, 413151); +INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES +(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00'); + INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES (1, 1, 2, 1, 1000000000000, 1, '2021-01-07 10:22:52'); -INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `home`, `description`) VALUES -(1, 'docker_stage2', 'docker stage2 gradido group', 'localhost', '/', 'gradido test group for docker and stage2'); - INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `running_hash`, `running_hash_version`, `updated`) VALUES -(1, 2, 'docker_stage2', 2, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34'); +(1, 3, 'dockerStage2', 1, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34'); diff --git a/skeema/gradido_login/users.sql b/skeema/gradido_login/users.sql index 4a3c9cc47..9de1bad49 100644 --- a/skeema/gradido_login/users.sql +++ b/skeema/gradido_login/users.sql @@ -4,7 +4,7 @@ CREATE TABLE `users` ( `first_name` varchar(150) NOT NULL, `last_name` varchar(255) DEFAULT '', `username` varchar(255) DEFAULT '', - `password` bigint unsigned NOT NULL, + `password` bigint unsigned DEFAULT '0', `pubkey` binary(32) DEFAULT NULL, `privkey` binary(80) DEFAULT NULL, `email_hash` binary(32) DEFAULT NULL, From 50631d1b470fbe210ecc6041704cccea97ea7181 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Mon, 15 Mar 2021 13:20:01 +0100 Subject: [PATCH 194/195] fix bug with disabled users --- src/cpp/HTTPInterface/LoginPage.cpp | 23 ++++++++++++----------- src/cpsp/.gitignore | 3 +++ src/cpsp/login.cpsp | 1 + 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 887768b58..5c510fe41 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -200,6 +200,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: if(mSession) { getErrors(mSession); sm->releaseSession(mSession); + mSession = nullptr; } sm->deleteLoginCookies(request, response); break; @@ -338,11 +339,11 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
"; // end include header.cpsp responseStream << "\n"; -#line 229 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 230 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\n"; responseStream << "
\n"; @@ -376,22 +377,22 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "\n"; responseStream << "
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\tgettext("E-Mail") ); responseStream << "\" value=\""; -#line 235 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 236 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( presetEmail ); responseStream << "\"/>\n"; responseStream << "\t\t\tgettext("Password") ); responseStream << "\" />\n"; responseStream << "\t\t \n"; responseStream << "\t\t
\n"; @@ -399,7 +400,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "
\n"; responseStream << "\t

"; -#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 243 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("You haven't any account yet? Please follow the link to create one.") ); responseStream << "

\n"; responseStream << "\t \n"; responseStream << "\t\t\t"; -#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("Create New Account") ); responseStream << "\n"; responseStream << "\t\t \n"; responseStream << "\t
\n"; responseStream << "\t\t\n"; diff --git a/src/cpsp/.gitignore b/src/cpsp/.gitignore index 863ee1751..7d12f04b4 100644 --- a/src/cpsp/.gitignore +++ b/src/cpsp/.gitignore @@ -1,2 +1,5 @@ /compile.sh /*.dll +/.vscode +/*.exe +/*.bat \ No newline at end of file diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index 9fce06102..c6491e405 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -176,6 +176,7 @@ if(mSession) { getErrors(mSession); sm->releaseSession(mSession); + mSession = nullptr; } sm->deleteLoginCookies(request, response); break; From d344551c834efd503ff5b86aa2863d1dae10effa Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 16 Mar 2021 11:59:51 +0100 Subject: [PATCH 195/195] disable client ip check in login called from community server, get correct client ip when forwarded from nginx --- src/cpp/HTTPInterface/LoginPage.cpp | 34 ++++++++++++++------------ src/cpp/JSONInterface/JsonGetLogin.cpp | 3 ++- src/cpsp/login.cpsp | 12 ++++++--- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 5c510fe41..1f50e11ba 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -129,13 +129,17 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: // get language // first check url, second check language header // for debugging client ip - auto client_ip = request.clientAddress(); + auto client_host = request.clientAddress().host(); + //auto client_ip = request.clientAddress(); + // X-Real-IP forwarded ip from nginx config + auto client_host_string = request.get("X-Real-IP", client_host.toString()); std::string clientIpString = "client ip: "; - clientIpString += client_ip.toString(); + client_host = Poco::Net::IPAddress(client_host_string); + clientIpString += client_host_string; Poco::Logger::get("requestLog").information(clientIpString); // debugging end - auto user_host = request.clientAddress().host(); - mSession->setClientIp(user_host); + mSession->setClientIp(client_host); + // TODO: check for valid url if(caller_uri != "") { mSession->setCallerUri(caller_uri); @@ -339,11 +343,11 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
"; // end include header.cpsp responseStream << "\n"; -#line 230 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\n"; responseStream << "
\n"; @@ -377,22 +381,22 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "\n"; responseStream << "
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\tgettext("E-Mail") ); responseStream << "\" value=\""; -#line 236 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 240 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( presetEmail ); responseStream << "\"/>\n"; responseStream << "\t\t\tgettext("Password") ); responseStream << "\" />\n"; responseStream << "\t\t \n"; responseStream << "\t\t
\n"; @@ -400,7 +404,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "
\n"; responseStream << "\t

"; -#line 243 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("You haven't any account yet? Please follow the link to create one.") ); responseStream << "

\n"; responseStream << "\t \n"; responseStream << "\t\t\t"; -#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 249 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("Create New Account") ); responseStream << "\n"; responseStream << "\t\t \n"; responseStream << "\t
\n"; responseStream << "\t\t\n"; diff --git a/src/cpp/JSONInterface/JsonGetLogin.cpp b/src/cpp/JSONInterface/JsonGetLogin.cpp index f85a05765..92ef5e887 100644 --- a/src/cpp/JSONInterface/JsonGetLogin.cpp +++ b/src/cpp/JSONInterface/JsonGetLogin.cpp @@ -16,7 +16,8 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params) auto pt = PendingTasksManager::getInstance(); auto observer = SingletonTaskObserver::getInstance(); - auto session_check_result = checkAndLoadSession(params, true); + //if(!mClientIp.isLoopback()) + auto session_check_result = checkAndLoadSession(params, false); if (session_check_result) { return session_check_result; } diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index c6491e405..e5947c496 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -105,13 +105,17 @@ // get language // first check url, second check language header // for debugging client ip - auto client_ip = request.clientAddress(); + auto client_host = request.clientAddress().host(); + //auto client_ip = request.clientAddress(); + // X-Real-IP forwarded ip from nginx config + auto client_host_string = request.get("X-Real-IP", client_host.toString()); std::string clientIpString = "client ip: "; - clientIpString += client_ip.toString(); + client_host = Poco::Net::IPAddress(client_host_string); + clientIpString += client_host_string; Poco::Logger::get("requestLog").information(clientIpString); // debugging end - auto user_host = request.clientAddress().host(); - mSession->setClientIp(user_host); + mSession->setClientIp(client_host); + // TODO: check for valid url if(caller_uri != "") { mSession->setCallerUri(caller_uri);