From 1206b6105db626d91b45d4d4b3d85eaf9e0eb249 Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Mon, 24 Aug 2020 18:24:48 +0200 Subject: [PATCH 01/46] 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 02/46] 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 03/46] 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 04/46] 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 05/46] 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 06/46] 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 07/46] 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 08/46] 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 09/46] 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 10/46] 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 11/46] 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 12/46] 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 13/46] 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 14/46] 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 15/46] 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 16/46] 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 17/46] 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 18/46] 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 19/46] 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 20/46] 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 21/46] 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 22/46] 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 23/46] 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 24/46] 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 25/46] 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 26/46] 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 27/46] 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 28/46] 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 29/46] 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 30/46] 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 31/46] 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 32/46] 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 33/46] 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 40/46] 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 41/46] 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 42/46] 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 43/46] 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 44/46] 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 45/46] 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 a4ab74b5c6b156337ad11ee98df7ef07e14ce36b Mon Sep 17 00:00:00 2001 From: einhornimmond - MarkX Date: Thu, 8 Oct 2020 11:51:23 +0200 Subject: [PATCH 46/46] 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