mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
merge with master
This commit is contained in:
commit
c8ea858ba5
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -15,16 +15,13 @@
|
||||
[submodule "login_server/dependencies/spirit-po"]
|
||||
path = login_server/dependencies/spirit-po
|
||||
url = https://github.com/cbeck88/spirit-po.git
|
||||
[submodule "login_server/dependencies/grpc"]
|
||||
path = login_server/dependencies/grpc
|
||||
url = https://github.com/grpc/grpc.git
|
||||
[submodule "login_server/dependencies/poco"]
|
||||
path = login_server/dependencies/poco
|
||||
url = https://github.com/pocoproject/poco.git
|
||||
[submodule "login_server/dependencies/cmake-modules"]
|
||||
path = login_server/dependencies/cmake-modules
|
||||
url = https://github.com/viaduck/cmake-modules.git
|
||||
|
||||
|
||||
[submodule "community_server/src/protobuf"]
|
||||
path = community_server/src/protobuf
|
||||
url = https://github.com/gradido/gradido_protocol.git
|
||||
@ -34,3 +31,6 @@
|
||||
[submodule "login_server/src/proto"]
|
||||
path = login_server/src/proto
|
||||
url = https://github.com/gradido/gradido_protocol.git
|
||||
[submodule "login_server/dependencies/protobuf"]
|
||||
path = login_server/dependencies/protobuf
|
||||
url = https://github.com/protocolbuffers/protobuf.git
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES
|
||||
(2, 'dockerStage2', 'docker stage2 gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2');
|
||||
|
||||
INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES
|
||||
(1, 0, 0, 3),
|
||||
(2, 0, 0, 3327),
|
||||
(3, 0, 0, 413151);
|
||||
|
||||
INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES
|
||||
(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00');
|
||||
|
||||
INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES
|
||||
(1, 1, 2, 1, 1000000000000, 1, '2021-01-07 10:22:52');
|
||||
|
||||
INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `running_hash`, `running_hash_version`, `updated`) VALUES
|
||||
(1, 3, 'dockerStage2', 1, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34');
|
||||
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ services:
|
||||
- ./login_server/dependencies:/code/dependencies
|
||||
- ./login_server/scripts:/code/scripts
|
||||
- ./configs/login_server:/etc/grd_login
|
||||
- login_build_alpine:/code/build
|
||||
- login_build_3:/code/build
|
||||
|
||||
|
||||
#########################################################
|
||||
@ -100,4 +100,4 @@ services:
|
||||
|
||||
volumes:
|
||||
frontend_node_modules:
|
||||
login_build_alpine:
|
||||
login_build_3:
|
||||
|
||||
@ -38,9 +38,12 @@ with:
|
||||
```json
|
||||
{
|
||||
"email": "max.musterman@gmail.de",
|
||||
"username": "Maxilein",
|
||||
"password": "123abcDE&"
|
||||
}
|
||||
```
|
||||
`username` or `email` must be present!
|
||||
If booth present, `email` will be used.
|
||||
|
||||
### Response
|
||||
In case of success returns:
|
||||
@ -50,6 +53,7 @@ In case of success returns:
|
||||
"state":"success",
|
||||
"user": {
|
||||
"created": 1614782270,
|
||||
"description": "",
|
||||
"disabled": false,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"email_checked": true,
|
||||
@ -69,6 +73,7 @@ In case of success returns:
|
||||
|
||||
- `user`: contain user object
|
||||
- `created`: timestamp on which account was created
|
||||
- `description`: description of user for other user
|
||||
- `disabled`: true if account was disabled, if disabled no login or coin transfer is possible
|
||||
- `email`: email of user
|
||||
- `email_checked`: true if user has successfully clicked on activation link in email
|
||||
@ -96,7 +101,9 @@ with:
|
||||
{
|
||||
"email":"max.musterman@gmail.de",
|
||||
"first_name":"Max",
|
||||
"last_name":"Musterman" ,
|
||||
"last_name":"Musterman",
|
||||
"username": "Maxilein",
|
||||
"description": "Tischler",
|
||||
"emailType": 2,
|
||||
"group_id": 1,
|
||||
"password":"123abcDE&",
|
||||
@ -104,6 +111,8 @@ with:
|
||||
}
|
||||
```
|
||||
|
||||
- `username`: (optional), mindestens 4 Zeichen, return error if already used
|
||||
- `description`: (optional), mindestens 4 Zeichen
|
||||
- `emailType`: control email-text sended with email verification code
|
||||
- 2: default, if user has registered directly
|
||||
- 5: if user was registered by an admin
|
||||
@ -167,6 +176,8 @@ with:
|
||||
"update": {
|
||||
"User.first_name": "Max",
|
||||
"User.last_name" : "Musterman",
|
||||
"User.username" : "Maxilein",
|
||||
"User.description" : "Tischler",
|
||||
"User.disabled": 0,
|
||||
"User.language": "de",
|
||||
"User.password": "1234"
|
||||
@ -237,6 +248,8 @@ with:
|
||||
"user.pubkeyhex",
|
||||
"user.first_name",
|
||||
"user.last_name",
|
||||
"user.username",
|
||||
"user.description",
|
||||
"user.disabled",
|
||||
"user.email_checked",
|
||||
"user.language"
|
||||
@ -271,6 +284,8 @@ Return only the fields which are defined in request
|
||||
- `user.pubkeyhex`: public key of user in hex-format
|
||||
- `user.first_name`: first name of user
|
||||
- `user.last_name`: last name of user
|
||||
- `user.username`: username of user (min 4 Character, unique per group)
|
||||
- `user.description`: profil text for user
|
||||
- `user.disabled`: User will be disabled if he wants a account delete but has transactions. Until transactions are saved in real blockchain, we need this data because the public key
|
||||
is in db only saved in state_users so if we delete this entry, validating all transactions is no longer possible. Disabled User cannot login and cannot receive transactions.
|
||||
- `email_checked`: If user has clicked on link in verification email (register), can only transfer gradidos if email_checked is 1
|
||||
@ -298,6 +313,7 @@ In case of success returns:
|
||||
"info":[],
|
||||
"user": {
|
||||
"created": 1614782270,
|
||||
"description": "Tischler"
|
||||
"disabled": false,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"email_checked": true,
|
||||
|
||||
@ -19,9 +19,7 @@ include_directories(
|
||||
"dependencies/mariadb-connector-c/include"
|
||||
"dependencies/mariadb-connector-c/build/include"
|
||||
"dependencies/spirit-po/include"
|
||||
"dependencies/grpc/include"
|
||||
"dependencies/grpc/third_party/protobuf/src"
|
||||
"dependencies/grpc/third_party/googletest/googletest/include"
|
||||
"dependencies/protobuf/src"
|
||||
"build"
|
||||
"build/proto"
|
||||
"build/http_pages"
|
||||
@ -39,56 +37,28 @@ IF(UNIX)
|
||||
"dependencies/poco/NetSSL_OpenSSL/include"
|
||||
)
|
||||
ENDIF()
|
||||
############################## config and add grpc ###################################
|
||||
|
||||
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)
|
||||
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")
|
||||
endif()
|
||||
|
||||
|
||||
set(BUILD_TESTING OFF)
|
||||
#set(gRPC_SSL_PROVIDER "package")
|
||||
add_subdirectory("dependencies/grpc/")
|
||||
#set(gRPC_SSL_PROVIDER "package")
|
||||
message(STATUS "Using gRPC via add_subdirectory.")
|
||||
|
||||
set(GRPC_LIBS libprotobuf grpc++_reflection grpc++)
|
||||
############################## find protobuf #########################################
|
||||
add_subdirectory(dependencies/protobuf/cmake)
|
||||
|
||||
############################## parse protobuf files ###################################
|
||||
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/proto GRADIDO_PROTO_MODEL_PATH)
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/proto/hedera/hedera-protobuf/src/main/proto HEDERA_PROTO_MODEL_PATH)
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/build/proto PROTOBINDING_PATH)
|
||||
file(MAKE_DIRECTORY ${PROTOBINDING_PATH})
|
||||
file(MAKE_DIRECTORY ${PROTOBINDING_PATH}/gradido)
|
||||
file(MAKE_DIRECTORY ${PROTOBINDING_PATH}/hedera)
|
||||
|
||||
FILE(GLOB DATAMODEL_GRADIDO_PROTOS "${GRADIDO_PROTO_MODEL_PATH}/gradido/*.proto")
|
||||
FILE(GLOB DATAMODEL_HEDERA_PROTOS "${HEDERA_PROTO_MODEL_PATH}/*.proto")
|
||||
|
||||
IF(WIN32)
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin PATHS "build/dependencies/grpc/bin/Debug")
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin PATHS "build/dependencies/grpc/bin/Release")
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/grpc/third_party/protobuf/bin/Debug" )
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/grpc/third_party/protobuf/bin/Release" )
|
||||
set(PROTOC_BIN_PATH "build/dependencies/protobuf/cmake/bin")
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "${PROTOC_BIN_PATH}/Debug" )
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "${PROTOC_BIN_PATH}/Release" )
|
||||
ELSE()
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin PATHS "build/dependencies/grpc/bin")
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/grpc/third_party/protobuf/bin" )
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/protobuf/cmake/bin" )
|
||||
ENDIF()
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/grpc/third_party/protobuf/src GOOGLE_PROTOBUF_INCLUDES)
|
||||
MESSAGE("protoc: ${PROTOBUF_PROTOC_EXECUTABLE} in build/dependencies/grpc/bin/${CMAKE_BUILD_TYPE}")
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/protobuf/src GOOGLE_PROTOBUF_INCLUDES)
|
||||
MESSAGE("protoc: ${PROTOBUF_PROTOC_EXECUTABLE} in build/dependencies/protobuf/bin/${CMAKE_BUILD_TYPE}")
|
||||
FOREACH(proto ${DATAMODEL_GRADIDO_PROTOS})
|
||||
FILE(TO_NATIVE_PATH ${proto} proto_native)
|
||||
get_filename_component(proto_parsed ${proto} NAME_WLE)
|
||||
@ -113,30 +83,6 @@ FOREACH(proto ${DATAMODEL_GRADIDO_PROTOS})
|
||||
|
||||
ENDFOREACH(proto)
|
||||
|
||||
FOREACH(proto ${DATAMODEL_HEDERA_PROTOS})
|
||||
FILE(TO_NATIVE_PATH ${proto} proto_native)
|
||||
get_filename_component(proto_parsed ${proto} NAME_WLE)
|
||||
FILE(TO_NATIVE_PATH ${PROTOBINDING_PATH}/hedera/${proto_parsed}.pb.h proto_parsed_native)
|
||||
IF(${proto_native} IS_NEWER_THAN ${proto_parsed_native})
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND
|
||||
${PROTOBUF_PROTOC_EXECUTABLE}
|
||||
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN}
|
||||
--proto_path=${HEDERA_PROTO_MODEL_PATH}
|
||||
--proto_path=${GOOGLE_PROTOBUF_INCLUDES}
|
||||
--cpp_out=${PROTOBINDING_PATH}/hedera
|
||||
--grpc_out ${PROTOBINDING_PATH}/hedera
|
||||
${proto_native}
|
||||
RESULT_VARIABLE rv
|
||||
)
|
||||
# Optional, but that can show the user if something have gone wrong with the proto generation
|
||||
IF(${rv})
|
||||
MESSAGE("Generation of data model returned ${rv} for proto ${proto_native}")
|
||||
ELSE()
|
||||
MESSAGE("Parsed: src/proto/hedera/hedera-protobuf/src/main/proto/${proto_parsed}.proto")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDFOREACH(proto)
|
||||
|
||||
############################## parse cpsp Files ####################################
|
||||
|
||||
@ -212,13 +158,11 @@ 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 MODEL_GRADIDO "src/cpp/model/gradido/*.h" "src/cpp/model/gradido/*.cpp")
|
||||
FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp")
|
||||
FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h")
|
||||
FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h")
|
||||
FILE(GLOB PROTO_GRADIDO "build/proto/gradido/*.cc" "build/proto/gradido/*.h")
|
||||
FILE(GLOB PROTO_HEDERA "build/proto/hedera/*.cc" "build/proto/hedera/*.h")
|
||||
|
||||
# used only for test project
|
||||
FILE(GLOB TEST "src/cpp/test/*.cpp" "src/cpp/test/*.h")
|
||||
@ -230,9 +174,9 @@ FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controll
|
||||
SET(LOCAL_SRCS
|
||||
${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} ${COMPILED_PAGES}
|
||||
${JSONInterface} ${CRYPTO}
|
||||
${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_HEDERA} ${MODEL_GRADIDO}
|
||||
${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_GRADIDO}
|
||||
${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS}
|
||||
${PROTO_GRADIDO} ${PROTO_HEDERA}
|
||||
${PROTO_GRADIDO}
|
||||
)
|
||||
SET(LOCAL_TEST_SRC
|
||||
${TEST} ${TEST_CRYPTO} ${TEST_MODEL} ${TEST_MODEL_TABLE} ${TEST_CONTROLLER}
|
||||
@ -243,13 +187,11 @@ 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\\gradido" FILES ${MODEL_GRADIDO})
|
||||
source_group("model" FILES ${MODEL})
|
||||
source_group("mysql" FILES ${MYSQL})
|
||||
@ -266,7 +208,6 @@ if(MSVC)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
add_executable(Gradido_LoginServer ${LOCAL_SRCS})
|
||||
|
||||
############################## config and add mariadb ###################################
|
||||
@ -314,11 +255,11 @@ ENDIF()
|
||||
target_link_libraries(Gradido_LoginServer ${GRPC_LIBS})
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(Gradido_LoginServer mariadbclient ${CONAN_LIBS})
|
||||
target_link_libraries(Gradido_LoginServer mariadbclient libprotobuf ${CONAN_LIBS})
|
||||
#TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi)
|
||||
#TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi)
|
||||
else() # unix
|
||||
target_link_libraries(Gradido_LoginServer ${POCO_LIBS} libmariadb sodium)
|
||||
target_link_libraries(Gradido_LoginServer ${POCO_LIBS} libmariadb sodium libprotobuf)
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 7d7e4567625db7cfebf8969a225948097a3f9f89
|
||||
1
login_server/dependencies/protobuf
Submodule
1
login_server/dependencies/protobuf
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0b8d13a1d4cd9be16ed8a2230577aa9c296aa1ca
|
||||
@ -5,15 +5,9 @@ fi
|
||||
if [ ! -d "../src/cpp/proto/gradido" ] ; then
|
||||
mkdir ../src/cpp/proto/gradido
|
||||
fi
|
||||
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
|
||||
PROTOC_PATH=../build/dependencies/protobuf/cmake/bin/Debug
|
||||
|
||||
$PROTOC_PATH/protoc.exe --cpp_out=../build/proto/gradido --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.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
|
||||
|
||||
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
CREATE TABLE `crypto_keys` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`private_key` varbinary(80) NOT NULL,
|
||||
`public_key` binary(32) NOT NULL,
|
||||
`crypto_key_type_id` int NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE(`public_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,12 +0,0 @@
|
||||
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',
|
||||
`network_type` int NOT NULL DEFAULT '0',
|
||||
`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`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,7 +0,0 @@
|
||||
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;
|
||||
@ -1,16 +0,0 @@
|
||||
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,
|
||||
`admin_key_id` int unsigned DEFAULT NULL,
|
||||
`submit_key_id` int unsigned DEFAULT NULL,
|
||||
`current_timeout` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
|
||||
`sequence_number` bigint unsigned DEFAULT '0',
|
||||
`running_hash` VARBINARY(64) DEFAULT NULL,
|
||||
`running_hash_version` int unsigned DEFAULT 0,
|
||||
`updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,10 +0,0 @@
|
||||
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;
|
||||
@ -1,7 +1,6 @@
|
||||
CREATE TABLE `pending_tasks` (
|
||||
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int UNSIGNED DEFAULT 0,
|
||||
`hedera_id` int UNSIGNED DEFAULT 0,
|
||||
`request` varbinary(2048) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
`finished` datetime DEFAULT '2000-01-01 000000',
|
||||
|
||||
@ -4,6 +4,7 @@ CREATE TABLE `users` (
|
||||
`first_name` varchar(150) NOT NULL,
|
||||
`last_name` varchar(255) DEFAULT '',
|
||||
`username` varchar(255) DEFAULT '',
|
||||
`description` text DEFAULT '',
|
||||
`password` bigint unsigned DEFAULT '0',
|
||||
`pubkey` binary(32) DEFAULT NULL,
|
||||
`privkey` binary(80) DEFAULT NULL,
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "SingletonManager/SessionManager.h"
|
||||
#include "SingletonManager/EmailManager.h"
|
||||
#include "SingletonManager/PendingTasksManager.h"
|
||||
#include "SingletonManager/CronManager.h"
|
||||
|
||||
#include "controller/User.h"
|
||||
|
||||
@ -168,7 +167,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
createConsoleFileAsyncLogger("emailLog", log_Path + "emailLog.txt");
|
||||
|
||||
// *************** load from config ********************************************
|
||||
|
||||
|
||||
std::string cfg_Path = Poco::Path::config() + "grd_login/";
|
||||
try {
|
||||
if(mConfigPath != "") {
|
||||
@ -224,7 +223,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
errorLog.error("[Gradido_LoginServer::main] Poco Exception by register MySQL Connector: %s", ex.displayText());
|
||||
return Application::EXIT_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
auto conn = ConnectionManager::getInstance();
|
||||
//conn->setConnection()
|
||||
//printf("try connect login server mysql db\n");
|
||||
@ -255,7 +254,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
errorLog.error("[Gradido_LoginServer::main] error init server SSL Client");
|
||||
return Application::EXIT_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
// schedule email verification resend
|
||||
controller::User::checkIfVerificationEmailsShouldBeResend(ServerConfig::g_CronJobsTimer);
|
||||
controller::User::addMissingEmailHashes();
|
||||
@ -281,14 +280,12 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
// load pending tasks not finished in last session
|
||||
PendingTasksManager::getInstance()->load();
|
||||
int php_server_ping = config().getInt("phpServer.ping", 600000);
|
||||
CronManager::getInstance()->init(php_server_ping);
|
||||
|
||||
printf("[Gradido_LoginServer::main] started in %s\n", usedTime.string().data());
|
||||
std::clog << "[Gradido_LoginServer::main] started in " << usedTime.string().data() << std::endl;
|
||||
// wait for CTRL-C or kill
|
||||
waitForTerminationRequest();
|
||||
|
||||
CronManager::getInstance()->stop();
|
||||
|
||||
// Stop the HTTPServer
|
||||
srv.stop();
|
||||
|
||||
@ -24,17 +24,11 @@
|
||||
#include "DebugMnemonicPage.h"
|
||||
#include "AdminCheckUserBackupPage.h"
|
||||
#include "TranslatePassphrasePage.h"
|
||||
#include "PassphrasedTransactionPage.h"
|
||||
#include "AdminUserPasswordResetPage.h"
|
||||
#include "RegisterDirectPage.h"
|
||||
#include "AdminGroupsPage.h"
|
||||
#include "AdminTopicPage.h"
|
||||
#include "AdminHederaAccountPage.h"
|
||||
#include "AdminNodeServerPage.h"
|
||||
#include "AdminNodeServerTestPage.h"
|
||||
|
||||
#include "DecodeTransactionPage.h"
|
||||
#include "RepairDefectPassphrasePage.h"
|
||||
|
||||
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
@ -121,7 +115,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
|
||||
// TODO: count invalid session requests from IP and block IP for some time to prevent brute force session hijacking
|
||||
// or use log file and configure fail2ban for this to do
|
||||
|
||||
|
||||
if (url_first_part == "/checkEmail") {
|
||||
//return new CheckEmailPage(s);
|
||||
//printf("url checkEmail\n");
|
||||
@ -147,12 +141,8 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
mLogging.information(dateTimeString + " decode");
|
||||
return basicSetup(new DecodeTransactionPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/passphrased_transaction") {
|
||||
return basicSetup(new PassphrasedTransactionPage, request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/adminNodeServerTest") {
|
||||
return basicSetup(new AdminNodeServerTestPage, request, timeUsed);
|
||||
}
|
||||
|
||||
|
||||
if (s) {
|
||||
if (externReferer != "") {
|
||||
|
||||
@ -178,9 +168,6 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (url_first_part == "/transform_passphrase") {
|
||||
return basicSetup(new TranslatePassphrasePage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/repairPassphrase") {
|
||||
return basicSetup(new RepairDefectPassphrasePage(s), request, timeUsed);
|
||||
}
|
||||
if (userModel && userModel->getRole() == model::table::ROLE_ADMIN) {
|
||||
if (url_first_part == "/adminRegister") {
|
||||
return basicSetup(new RegisterAdminPage(s), request, timeUsed);
|
||||
@ -200,21 +187,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (url_first_part == "/groups") {
|
||||
return basicSetup(new AdminGroupsPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/topic") {
|
||||
return basicSetup(new AdminTopicPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/hedera_account") {
|
||||
return basicSetup(new AdminHederaAccountPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/nodes") {
|
||||
return basicSetup(new AdminNodeServerPage(s), request, timeUsed);
|
||||
}
|
||||
}
|
||||
|
||||
if(url_first_part == "/logout") {
|
||||
sm->releaseSession(s);
|
||||
// remove cookie(s)
|
||||
|
||||
|
||||
//printf("session released\n");
|
||||
return basicSetup(new LoginPage(nullptr), request, timeUsed);
|
||||
}
|
||||
@ -223,7 +201,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
sm->releaseSession(s);
|
||||
|
||||
return basicSetup(new LoginPage(nullptr), request, timeUsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto sessionState = s->getSessionState();
|
||||
//printf("session state: %s\n", s->getSessionStateString());
|
||||
@ -241,7 +219,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (url_first_part == "/login" || url_first_part == "/") {
|
||||
return basicSetup(new LoginPage(s), request, timeUsed);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if (url_first_part == "/config") {
|
||||
@ -305,7 +283,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
response.addCookie(Poco::Net::HTTPCookie("user", std::to_string(cookie_id)));
|
||||
*/
|
||||
}
|
||||
else {
|
||||
else {
|
||||
//sm->releaseSession(session);
|
||||
return basicSetup(new CheckEmailPage(session), request, timeUsed);
|
||||
}
|
||||
@ -325,7 +303,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
//! -2 = critical error
|
||||
//! 0 = ok
|
||||
*/
|
||||
// update session, mark as verified
|
||||
// update session, mark as verified
|
||||
int retUpdateEmailVerification = session->updateEmailVerification(verificationCode);
|
||||
printf("[%s] return from update email verification: %d\n", __FUNCTION__, retUpdateEmailVerification);
|
||||
if (0 == retUpdateEmailVerification) {
|
||||
@ -340,7 +318,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
pageRequestHandler = new PassphrasePage(session);
|
||||
}
|
||||
return basicSetup(pageRequestHandler, request, timeUsed);
|
||||
|
||||
|
||||
}
|
||||
else if (1 == retUpdateEmailVerification) {
|
||||
//auto user = session->getUser();
|
||||
@ -358,7 +336,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
else if (-2 == retUpdateEmailVerification) {
|
||||
return basicSetup(new Error500Page(session), request, timeUsed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (session) {
|
||||
sm->releaseSession(session);
|
||||
|
||||
@ -15,6 +15,8 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
std::string password;
|
||||
std::string username;
|
||||
std::string description;
|
||||
bool login_after_register = false;
|
||||
int emailType;
|
||||
int group_id = 1;
|
||||
@ -36,18 +38,27 @@ 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);
|
||||
|
||||
auto group_id_obj = paramJsonObject->get("group_id");
|
||||
auto username_obj = paramJsonObject->get("username");
|
||||
auto description_obj = paramJsonObject->get("description");
|
||||
|
||||
if(!group_id_obj.isEmpty()) {
|
||||
group_id_obj.convert(group_id);
|
||||
}
|
||||
|
||||
if (!username_obj.isEmpty()) {
|
||||
username_obj.convert(username);
|
||||
}
|
||||
if (!description_obj.isEmpty()) {
|
||||
description_obj.convert(description);
|
||||
}
|
||||
if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) {
|
||||
paramJsonObject->get("password").convert(password);
|
||||
}
|
||||
if (!paramJsonObject->isNull("login_after_register")) {
|
||||
paramJsonObject->get("login_after_register").convert(login_after_register);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
return stateError("json exception", ex.displayText());
|
||||
@ -85,6 +96,15 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
|
||||
group_was_not_set = true;
|
||||
}
|
||||
user = controller::User::create(email, first_name, last_name, group_id);
|
||||
if (username.size() > 3) {
|
||||
if (user->isUsernameAlreadyUsed(username)) {
|
||||
return stateError("username already in use");
|
||||
}
|
||||
user->getModel()->setUsername(username);
|
||||
}
|
||||
if (description.size() > 3) {
|
||||
user->getModel()->setDescription(description);
|
||||
}
|
||||
auto userModel = user->getModel();
|
||||
Session* session = nullptr;
|
||||
|
||||
|
||||
@ -121,6 +121,12 @@ Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
|
||||
else if (parameterString == "user.last_name") {
|
||||
jsonUser.set("last_name", user_model->getLastName());
|
||||
}
|
||||
else if (parameterString == "user.username") {
|
||||
jsonUser.set("username", user_model->getUsername());
|
||||
}
|
||||
else if (parameterString == "user.description") {
|
||||
jsonUser.set("description", user_model->getDescription());
|
||||
}
|
||||
else if (parameterString == "user.disabled") {
|
||||
jsonUser.set("disabled", user_model->isDisabled());
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "JsonCreateUser.h"
|
||||
#include "JsonGetLogin.h"
|
||||
#include "JsonUnknown.h"
|
||||
#include "JsonTransaction.h"
|
||||
#include "JsonGetRunningUserTasks.h"
|
||||
#include "JsonGetUsers.h"
|
||||
#include "JsonLoginViaEmailVerificationCode.h"
|
||||
@ -28,7 +27,7 @@
|
||||
#include "JsonSearch.h"
|
||||
|
||||
|
||||
JsonRequestHandlerFactory::JsonRequestHandlerFactory()
|
||||
JsonRequestHandlerFactory::JsonRequestHandlerFactory()
|
||||
: mRemoveGETParameters("^/([a-zA-Z0-9_-]*)"), mLogging(Poco::Logger::get("requestLog"))
|
||||
{
|
||||
}
|
||||
@ -75,9 +74,6 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
else if (url_first_part == "/checkSessionState") {
|
||||
return new JsonCheckSessionState;
|
||||
}
|
||||
else if (url_first_part == "/checkTransaction") {
|
||||
return new JsonTransaction;
|
||||
}
|
||||
else if (url_first_part == "/createTransaction") {
|
||||
return new JsonCreateTransaction;
|
||||
}
|
||||
@ -86,7 +82,7 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
}
|
||||
else if (url_first_part == "/getUsers") {
|
||||
return new JsonGetUsers;
|
||||
}
|
||||
}
|
||||
else if (url_first_part == "/networkInfos") {
|
||||
return new JsonNetworkInfos;
|
||||
}
|
||||
@ -136,7 +132,7 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
else if (url_first_part == "/logout") {
|
||||
return new JsonLogout(client_host);
|
||||
}
|
||||
|
||||
|
||||
return new JsonUnknown;
|
||||
}
|
||||
|
||||
|
||||
@ -1,171 +0,0 @@
|
||||
#include "JsonTransaction.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params)
|
||||
{
|
||||
Poco::JSON::Object* result = new Poco::JSON::Object;
|
||||
int session_id = 0;
|
||||
|
||||
// if is json object
|
||||
if (params.type() == typeid(Poco::JSON::Object::Ptr)) {
|
||||
Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
try {
|
||||
/// Throws a RangeException if the value does not fit
|
||||
/// into the result variable.
|
||||
/// Throws a NotImplementedException if conversion is
|
||||
/// not available for the given type.
|
||||
/// Throws InvalidAccessException if Var is empty.
|
||||
paramJsonObject->get("session_id").convert(session_id);
|
||||
auto sm = SessionManager::getInstance();
|
||||
if (session_id != 0) {
|
||||
auto session = sm->getSession(session_id);
|
||||
if (!session) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "session not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
int balance = 0;
|
||||
|
||||
if (!paramJsonObject->isNull("balance")) {
|
||||
paramJsonObject->get("balance").convert(balance);
|
||||
if (balance) {
|
||||
auto nu = session->getNewUser();
|
||||
if (!nu.isNull()) {
|
||||
nu->setBalance(balance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string transactionBase64String;
|
||||
Poco::Dynamic::Var transaction_base64 = paramJsonObject->get("transaction_base64");
|
||||
int alreadyEnlisted = 0;
|
||||
bool auto_sign = false;
|
||||
auto auto_sign_json = paramJsonObject->get("auto_sign");
|
||||
if (!auto_sign_json.isEmpty()) {
|
||||
auto_sign_json.convert(auto_sign);
|
||||
}
|
||||
|
||||
if (transaction_base64.isString()) {
|
||||
paramJsonObject->get("transaction_base64").convert(transactionBase64String);
|
||||
|
||||
if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) {
|
||||
if (auto_sign) {
|
||||
auto errorJson = session->getErrorsArray();
|
||||
result->set("state", "error");
|
||||
result->set("msg", "error processing transaction");
|
||||
result->set("details", errorJson);
|
||||
return result;
|
||||
}
|
||||
auto lastError = session->getLastError();
|
||||
if (lastError) delete lastError;
|
||||
result->set("state", "error");
|
||||
result->set("msg", "already enlisted");
|
||||
return result;
|
||||
}
|
||||
|
||||
} else {
|
||||
Poco::DynamicStruct ds = *paramJsonObject;
|
||||
int alreadyEnlisted = 0;
|
||||
|
||||
for (int i = 0; i < ds["transaction_base64"].size(); i++) {
|
||||
ds["transaction_base64"][i].convert(transactionBase64String);
|
||||
if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) {
|
||||
auto lastError = session->getLastError();
|
||||
if (lastError) delete lastError;
|
||||
alreadyEnlisted++;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyEnlisted > 0) {
|
||||
result->set("state", "warning");
|
||||
result->set("msg", std::to_string(alreadyEnlisted) + " already enlisted");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
result->set("state", "success");
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[JsonTransaction::handle] try to use params as jsonObject: %s\n", ex.displayText().data());
|
||||
result->set("state", "error");
|
||||
result->set("msg", "json exception");
|
||||
result->set("details", ex.displayText());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (params.isVector()) {
|
||||
const Poco::URI::QueryParameters queryParams = params.extract<Poco::URI::QueryParameters>();
|
||||
auto transactionIT = queryParams.begin();
|
||||
for (auto it = queryParams.begin(); it != queryParams.end(); it++) {
|
||||
if (it->first == "session_id") {
|
||||
session_id = stoi(it->second);
|
||||
//break;
|
||||
}
|
||||
else if (it->first == "transaction_base64") {
|
||||
transactionIT = it;
|
||||
}
|
||||
}
|
||||
if (session_id) {
|
||||
auto sm = SessionManager::getInstance();
|
||||
auto session = sm->getSession(session_id);
|
||||
if (!session) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "session not found");
|
||||
return result;
|
||||
}
|
||||
if (!session->startProcessingTransaction(transactionIT->second)) {
|
||||
auto lastError = session->getLastError();
|
||||
if (lastError) delete lastError;
|
||||
result->set("state", "error");
|
||||
result->set("msg", "already enlisted");
|
||||
return result;
|
||||
}
|
||||
result->set("state", "success");
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "session id not set");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (params.isStruct()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "struct not implemented yet");
|
||||
}
|
||||
else if (params.isArray()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "array not implemented yet");
|
||||
}
|
||||
else if (params.isList()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "list not implemented yet");
|
||||
}
|
||||
else if (params.isString()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "string not implemented yet");
|
||||
}
|
||||
else if (params.isDeque()) {
|
||||
result->set("state", "error");
|
||||
result->set("meg", "deque not implemented yet");
|
||||
}
|
||||
else {
|
||||
|
||||
result->set("state", "error");
|
||||
result->set("msg", "format not implemented");
|
||||
result->set("details", std::string(params.type().name()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
#ifndef __JSON_INTERFACE_JSON_TRANSACTION_
|
||||
#define __JSON_INTERFACE_JSON_TRANSACTION_
|
||||
|
||||
#include "JsonRequestHandler.h"
|
||||
|
||||
class Session;
|
||||
|
||||
class JsonTransaction : public JsonRequestHandler
|
||||
{
|
||||
public:
|
||||
Poco::JSON::Object* handle(Poco::Dynamic::Var params);
|
||||
|
||||
protected:
|
||||
bool startProcessingTransaction(Session* session, const std::string& transactionBase64);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // __JSON_INTERFACE_JSON_TRANSACTION_
|
||||
@ -21,6 +21,7 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
|
||||
// incoming
|
||||
|
||||
std::string email;
|
||||
std::string username;
|
||||
std::string password;
|
||||
|
||||
// if is json object
|
||||
@ -32,8 +33,17 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
|
||||
/// not available for the given type.
|
||||
/// Throws InvalidAccessException if Var is empty.
|
||||
try {
|
||||
paramJsonObject->get("email").convert(email);
|
||||
//paramJsonObject->get("email").convert(email);
|
||||
paramJsonObject->get("password").convert(password);
|
||||
auto email_obj = paramJsonObject->get("email");
|
||||
auto username_obj = paramJsonObject->get("username");
|
||||
|
||||
if (!email_obj.isEmpty()) {
|
||||
email_obj.convert(email);
|
||||
}
|
||||
if (!username_obj.isEmpty()) {
|
||||
username_obj.convert(username);
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
return stateError("json exception", ex.displayText());
|
||||
@ -43,13 +53,24 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
|
||||
return stateError("parameter format unknown");
|
||||
}
|
||||
|
||||
|
||||
if (!email.size() || !sm->isValid(email, VALIDATE_EMAIL)) {
|
||||
return stateError("invalid or empty email");
|
||||
if (!email.size() && !username.size()) {
|
||||
return stateError("no email or username given");
|
||||
}
|
||||
|
||||
auto user = controller::User::create();
|
||||
if (1 != user->load(email)) {
|
||||
return stateError("user with email not found", email);
|
||||
if (email.size()) {
|
||||
if (!sm->isValid(email, VALIDATE_EMAIL)) {
|
||||
return stateError("invalid email");
|
||||
}
|
||||
if (1 != user->load(email)) {
|
||||
return stateError("user with email not found", email);
|
||||
}
|
||||
}
|
||||
else if (username.size() > 0) {
|
||||
if (1 != user->load(username)) {
|
||||
return stateError("user with username not found", username);
|
||||
}
|
||||
email = user->getModel()->getEmail();
|
||||
}
|
||||
|
||||
NotificationList pwd_errors;
|
||||
|
||||
@ -86,6 +86,32 @@ Poco::JSON::Object* JsonUpdateUserInfos::handle(Poco::Dynamic::Var params)
|
||||
extractet_values++;
|
||||
}
|
||||
}
|
||||
else if ("User.username" == name && value.size() > 3) {
|
||||
if (!value.isString()) {
|
||||
jsonErrorsArray.add("User.username isn't a string");
|
||||
}
|
||||
else {
|
||||
auto new_username = value.toString();
|
||||
if (user_model->getUsername() != new_username) {
|
||||
if (user->isUsernameAlreadyUsed(new_username)) {
|
||||
jsonErrorsArray.add("username already used");
|
||||
}
|
||||
else {
|
||||
user_model->setUsername(new_username);
|
||||
extractet_values++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("User.description" == name && value.size() > 3) {
|
||||
if (!value.isString()) {
|
||||
jsonErrorsArray.add("description isn't a string");
|
||||
}
|
||||
else {
|
||||
user_model->setDescription(value.toString());
|
||||
extractet_values++;
|
||||
}
|
||||
}
|
||||
else if ("User.disabled" == name) {
|
||||
if (value.isBoolean()) {
|
||||
bool disabled;
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include "Poco/Environment.h"
|
||||
|
||||
#include "model/table/HederaAccount.h"
|
||||
|
||||
|
||||
using Poco::Net::SSLManager;
|
||||
@ -62,9 +61,6 @@ namespace ServerConfig {
|
||||
std::string g_gRPCRelayServerFullURL;
|
||||
MemoryBin* g_CryptoAppSecret = nullptr;
|
||||
AllowUnsecure g_AllowUnsecureFlags = NOT_UNSECURE;
|
||||
HederaConsensusMessageFormat g_ConsensusMessageFormat = HEDERA_CONSENSUS_FORMAT_BINARY;
|
||||
HederaNetworkType g_HederaNetworkType = HEDERA_TESTNET;
|
||||
Poco::Timespan g_HederaDefaultTimeout;
|
||||
|
||||
#ifdef __linux__
|
||||
#include <stdio.h>
|
||||
@ -157,36 +153,6 @@ namespace ServerConfig {
|
||||
return SERVER_TYPE_PRODUCTION;
|
||||
}
|
||||
|
||||
HederaConsensusMessageFormat getHederaConsensusMessageFormatFromString(const std::string& hederaConsensusMessageFormatString)
|
||||
{
|
||||
if ("json" == hederaConsensusMessageFormatString) {
|
||||
return HEDERA_CONSENSUS_FORMAT_JSON;
|
||||
}
|
||||
if ("binary" == hederaConsensusMessageFormatString || "bin" == hederaConsensusMessageFormatString) {
|
||||
return HEDERA_CONSENSUS_FORMAT_BINARY;
|
||||
}
|
||||
if ("base64" == hederaConsensusMessageFormatString) {
|
||||
return HEDERA_CONSENSUS_FORMAT_BASE64_URLSAVE_NO_PADDING;
|
||||
}
|
||||
return HEDERA_CONSENSUS_FORMAT_BINARY;
|
||||
}
|
||||
|
||||
const char* mnemonicTypeToString(Mnemonic_Types type)
|
||||
{
|
||||
/*
|
||||
MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER,
|
||||
MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES,
|
||||
MNEMONIC_BIP0039_SORTED_ORDER
|
||||
*/
|
||||
switch(type) {
|
||||
case MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER: return "german random order";
|
||||
case MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES: return "german random order fixed cases";
|
||||
case MNEMONIC_BIP0039_SORTED_ORDER: return "BIP 0039 sorted";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool loadMnemonicWordLists()
|
||||
{
|
||||
@ -265,14 +231,6 @@ namespace ServerConfig {
|
||||
|
||||
g_devDefaultGroup = cfg.getString("dev.default_group", "");
|
||||
|
||||
auto hedera_consensus_message_format_string = cfg.getString("hedera.consensus.message_format", "bin");
|
||||
g_ConsensusMessageFormat = getHederaConsensusMessageFormatFromString(hedera_consensus_message_format_string);
|
||||
|
||||
auto hedera_network_type_string = cfg.getString("hedera.nettype", "Testnet");
|
||||
g_HederaNetworkType = model::table::HederaAccount::hederaNetworkTypeFromString(hedera_network_type_string);
|
||||
if (HEDERA_UNKNOWN == g_HederaNetworkType) {
|
||||
g_HederaNetworkType = HEDERA_TESTNET;
|
||||
}
|
||||
|
||||
// app secret for encrypt user private keys
|
||||
// TODO: encrypt with server admin key
|
||||
@ -299,7 +257,6 @@ namespace ServerConfig {
|
||||
g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_ALLOW_ALL_PASSWORDS);
|
||||
}
|
||||
|
||||
g_HederaDefaultTimeout = cfg.getInt("hedera.default_timeout", 5);
|
||||
|
||||
g_gRPCRelayServerFullURL = cfg.getString("grpc.server", "");
|
||||
|
||||
|
||||
@ -48,21 +48,6 @@ namespace ServerConfig {
|
||||
UNSECURE_ALLOW_ALL_PASSWORDS = 8
|
||||
};
|
||||
|
||||
enum HederaConsensusMessageFormat {
|
||||
HEDERA_CONSENSUS_FORMAT_BINARY,
|
||||
HEDERA_CONSENSUS_FORMAT_JSON,
|
||||
HEDERA_CONSENSUS_FORMAT_BASE64_URLSAVE_NO_PADDING
|
||||
};
|
||||
|
||||
enum HederaNetworkType {
|
||||
HEDERA_MAINNET,
|
||||
HEDERA_TESTNET,
|
||||
HEDERA_NET_COUNT,
|
||||
HEDERA_UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
extern Mnemonic g_Mnemonic_WordLists[MNEMONIC_MAX];
|
||||
|
||||
@ -92,9 +77,6 @@ namespace ServerConfig {
|
||||
extern std::string g_gRPCRelayServerFullURL;
|
||||
extern MemoryBin* g_CryptoAppSecret;
|
||||
extern AllowUnsecure g_AllowUnsecureFlags;
|
||||
extern HederaConsensusMessageFormat g_ConsensusMessageFormat;
|
||||
extern HederaNetworkType g_HederaNetworkType;
|
||||
extern Poco::Timespan g_HederaDefaultTimeout;
|
||||
|
||||
|
||||
bool loadMnemonicWordLists();
|
||||
@ -102,7 +84,6 @@ namespace ServerConfig {
|
||||
bool initEMailAccount(const Poco::Util::LayeredConfiguration& cfg);
|
||||
bool initSSLClientContext();
|
||||
|
||||
const char* mnemonicTypeToString(Mnemonic_Types type);
|
||||
|
||||
void writeToFile(std::istream& datas, std::string fileName);
|
||||
|
||||
|
||||
@ -1,200 +0,0 @@
|
||||
#include "CronManager.h"
|
||||
#include "../lib/JsonRequest.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
|
||||
|
||||
CronManager::CronManager()
|
||||
: mInitalized(false), mMainTimer(1000, 600000)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CronManager::~CronManager()
|
||||
{
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
|
||||
mMainTimer.stop();
|
||||
mInitalized = false;
|
||||
|
||||
}
|
||||
|
||||
CronManager* CronManager::getInstance()
|
||||
{
|
||||
static CronManager one;
|
||||
return &one;
|
||||
}
|
||||
|
||||
bool CronManager::init(long defaultPeriodicIntervallMilliseconds/* = 600000*/)
|
||||
{
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
mInitalized = true;
|
||||
controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_COMMUNITY);
|
||||
|
||||
mDefaultIntervalMilliseconds = defaultPeriodicIntervallMilliseconds;
|
||||
mMainTimer.setPeriodicInterval(defaultPeriodicIntervallMilliseconds);
|
||||
Poco::TimerCallback<CronManager> callback(*this, &CronManager::runUpdateStep);
|
||||
mMainTimer.start(callback);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CronManager::stop()
|
||||
{
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
mInitalized = false;
|
||||
mMainTimer.stop();
|
||||
}
|
||||
|
||||
void CronManager::runUpdateStep(Poco::Timer& timer)
|
||||
{
|
||||
auto current = Poco::DateTime();
|
||||
//printf("%s [CronManager::runUpdateStep] \n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data());
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
if (!mInitalized) {
|
||||
return;
|
||||
}
|
||||
mNodeServersToPingMutex.lock();
|
||||
for (auto it = mNodeServersToPing.begin(); it != mNodeServersToPing.end(); it++)
|
||||
{
|
||||
// TODO: Make sure that task not already running, for example if community server needs more time for processing that between calls
|
||||
// or with schedule update run to short time between calls
|
||||
UniLib::controller::TaskPtr ping_node_server_task(new PingServerTask(*it));
|
||||
ping_node_server_task->scheduleTask(ping_node_server_task);
|
||||
}
|
||||
mNodeServersToPingMutex.unlock();
|
||||
|
||||
mTimestampsMutex.lock();
|
||||
//printf("update timestamp sizes: %d\n", mUpdateTimestamps.size());
|
||||
bool timerRestarted = false;
|
||||
|
||||
if (mUpdateTimestamps.size() > 0)
|
||||
{
|
||||
Poco::Timestamp now;
|
||||
// update maximal once per second
|
||||
now += Poco::Timespan(1, 0);
|
||||
while (mUpdateTimestamps.size() > 0 && mUpdateTimestamps.front() < now) {
|
||||
// printf("remove update time in past: %d\n", mUpdateTimestamps.front().epochTime());
|
||||
mUpdateTimestamps.pop_front();
|
||||
}
|
||||
if (mUpdateTimestamps.size() > 0) {
|
||||
Poco::Timespan next_run = mUpdateTimestamps.front() - now;
|
||||
//printf("timer restart called with: %d\n", next_run.seconds());
|
||||
//mMainTimer.setPeriodicInterval(next_run.totalMilliseconds());
|
||||
mMainTimer.restart(next_run.totalMilliseconds());
|
||||
mUpdateTimestamps.pop_front();
|
||||
timerRestarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!timerRestarted && mMainTimer.getPeriodicInterval() != mDefaultIntervalMilliseconds) {
|
||||
//printf("reset to default interval\n");
|
||||
mMainTimer.setPeriodicInterval(mDefaultIntervalMilliseconds);
|
||||
//mMainTimer.restart(mDefaultIntervalMilliseconds);
|
||||
}
|
||||
mTimestampsMutex.unlock();
|
||||
//printf("[CronManager::runUpdateStep] end\n");
|
||||
}
|
||||
|
||||
void CronManager::scheduleUpdateRun(Poco::Timespan timespanInFuture)
|
||||
{
|
||||
Poco::Timestamp timestamp;
|
||||
timestamp += timespanInFuture;
|
||||
|
||||
mTimestampsMutex.lock();
|
||||
//printf("[CronManager::scheduleUpdateRun] push:\n%d\n", timestamp.epochTime());
|
||||
mUpdateTimestamps.push_back(timestamp);
|
||||
mUpdateTimestamps.sort();
|
||||
auto frontTimestamp = mUpdateTimestamps.front();
|
||||
auto backTimestamp = mUpdateTimestamps.back();
|
||||
//printf("[CronManager::scheduleUpdateRun] front timestamp and back timestamp:\n%d\n%d\n", frontTimestamp.epochTime(), backTimestamp.epochTime());
|
||||
//printf("current: \n%d\n", Poco::Timestamp().epochTime());
|
||||
Poco::Timespan next_run = mUpdateTimestamps.front() - Poco::Timestamp();
|
||||
|
||||
Poco::DateTime now;
|
||||
std::string now_string = Poco::DateTimeFormatter::format(now, "%d.%m.%y %H:%M:%S.%i");
|
||||
//printf("%s [CronManager::scheduleUpdateRun] next run in %d seconds, %d millis (intervall: %d, default: %d)\n",
|
||||
//now_string.data(), next_run.seconds(), next_run.milliseconds(), mMainTimer.getPeriodicInterval(), mDefaultIntervalMilliseconds);
|
||||
if (next_run.seconds() > 0 && mMainTimer.getPeriodicInterval() == mDefaultIntervalMilliseconds) {
|
||||
if (mMainWorkMutex.tryLock(100)) {
|
||||
mMainTimer.restart(next_run.totalMilliseconds());
|
||||
mUpdateTimestamps.pop_front();
|
||||
mMainWorkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
mTimestampsMutex.unlock();
|
||||
//printf("[CronManager::scheduleUpdateRun] end\n");
|
||||
}
|
||||
|
||||
|
||||
void CronManager::addNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
{
|
||||
if (nodeServer.isNull() || !nodeServer->getModel()) {
|
||||
return;
|
||||
}
|
||||
if (isNodeServerInList(nodeServer)) {
|
||||
return;
|
||||
}
|
||||
mNodeServersToPingMutex.lock();
|
||||
mNodeServersToPing.push_back(nodeServer);
|
||||
mNodeServersToPingMutex.unlock();
|
||||
|
||||
}
|
||||
void CronManager::removeNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
{
|
||||
if (nodeServer.isNull() || !nodeServer->getModel()) {
|
||||
return;
|
||||
}
|
||||
mNodeServersToPingMutex.lock();
|
||||
int node_server_id = nodeServer->getModel()->getID();
|
||||
for (auto it = mNodeServersToPing.begin(); it != mNodeServersToPing.end(); it++) {
|
||||
if ((*it)->getModel()->getID() == node_server_id) {
|
||||
mNodeServersToPing.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mNodeServersToPingMutex.unlock();
|
||||
}
|
||||
|
||||
bool CronManager::isNodeServerInList(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
{
|
||||
bool result = false;
|
||||
mNodeServersToPingMutex.lock();
|
||||
int node_server_id = nodeServer->getModel()->getID();
|
||||
for (auto it = mNodeServersToPing.begin(); it != mNodeServersToPing.end(); it++) {
|
||||
if ((*it)->getModel()->getID() == node_server_id) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mNodeServersToPingMutex.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ***********************************************************************************************************
|
||||
PingServerTask::PingServerTask(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
: CPUTask(ServerConfig::g_CPUScheduler), mNodeServer(nodeServer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PingServerTask::~PingServerTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int PingServerTask::run()
|
||||
{
|
||||
//return 0;
|
||||
auto current = Poco::DateTime();
|
||||
if (model::table::NODE_SERVER_GRADIDO_COMMUNITY == mNodeServer->getModel()->getNodeServerType()) {
|
||||
std::string url_port = mNodeServer->getModel()->getUrlWithPort();
|
||||
printf("%s [PingServerTask::run] call update for %s\n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data(), url_port.data());
|
||||
|
||||
auto json_request = mNodeServer->createJsonRequest();
|
||||
json_request.request("updateReadNode");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_CRON_MANAGER_H
|
||||
#define __GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_CRON_MANAGER_H
|
||||
|
||||
#include "Poco/Timer.h"
|
||||
#include "../controller/NodeServer.h"
|
||||
#include "../tasks/CPUTask.h"
|
||||
|
||||
|
||||
/*!
|
||||
* \author: Dario Rekowski
|
||||
*
|
||||
* \date: 2020-11-03
|
||||
*
|
||||
* \brief: Manager for "Cron"-like Tasks.
|
||||
*
|
||||
* Ping for example community server to get new blocks from nodes
|
||||
* or Hedera Tasks to (re)try receiving Transaction Receipts
|
||||
*
|
||||
*/
|
||||
class CronManager
|
||||
{
|
||||
public:
|
||||
~CronManager();
|
||||
|
||||
static CronManager* getInstance();
|
||||
|
||||
bool init(long defaultPeriodicIntervallMilliseconds = 600000);
|
||||
void stop();
|
||||
|
||||
void runUpdateStep(Poco::Timer& timer);
|
||||
void scheduleUpdateRun(Poco::Timespan timespanInFuture);
|
||||
|
||||
|
||||
void addNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
void removeNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
|
||||
protected:
|
||||
CronManager();
|
||||
|
||||
bool isNodeServerInList(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
bool mInitalized;
|
||||
|
||||
Poco::Timer mMainTimer;
|
||||
std::list<Poco::AutoPtr<controller::NodeServer>> mNodeServersToPing;
|
||||
std::list<Poco::Timestamp> mUpdateTimestamps;
|
||||
Poco::FastMutex mNodeServersToPingMutex;
|
||||
Poco::FastMutex mMainWorkMutex;
|
||||
Poco::FastMutex mTimestampsMutex;
|
||||
long mDefaultIntervalMilliseconds;
|
||||
};
|
||||
|
||||
class PingServerTask : public UniLib::controller::CPUTask
|
||||
{
|
||||
public:
|
||||
PingServerTask(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
virtual ~PingServerTask();
|
||||
|
||||
const char* getResourceType() const { return "PingServerTask"; }
|
||||
|
||||
int run();
|
||||
|
||||
protected:
|
||||
Poco::AutoPtr<controller::NodeServer> mNodeServer;
|
||||
};
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_CRON_MANAGER_H
|
||||
@ -1,150 +0,0 @@
|
||||
|
||||
#include "CryptoKey.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
CryptoKey::CryptoKey(model::table::CryptoKey* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
|
||||
CryptoKey::~CryptoKey()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user, bool saveEncrypted/* = true*/)
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
MemoryBin* private_key = nullptr;
|
||||
auto public_key = hederaKeyPair->getPublicKeyCopy();
|
||||
|
||||
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(private_key);
|
||||
mm->releaseMemory(public_key);
|
||||
|
||||
auto cryptoKey = new CryptoKey(db);
|
||||
return Poco::AutoPtr<CryptoKey>(cryptoKey);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> 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>(cryptoKey);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> CryptoKey::load(MemoryBin* publicKey)
|
||||
{
|
||||
return load(*publicKey, publicKey->size());
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> 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<Poco::Data::BLOB>("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;
|
||||
}
|
||||
|
||||
std::unique_ptr<KeyPairHedera> CryptoKey::getKeyPair(Poco::AutoPtr<controller::User> user) const
|
||||
{
|
||||
auto model = getModel();
|
||||
assert(model);
|
||||
|
||||
if (!model->isEncrypted()) {
|
||||
return getKeyPair();
|
||||
}
|
||||
|
||||
if (!model->hasPrivateKey()) {
|
||||
printf("[CryptoKey::getKeyPair] return null, no private key\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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<KeyPairHedera>(clearPrivateKey->data(), clearPrivateKey->size(), model->getPublicKey(), model->getPublicKeySize());
|
||||
mm->releaseMemory(clearPrivateKey);
|
||||
return key_pair;
|
||||
}
|
||||
|
||||
std::unique_ptr<KeyPairHedera> 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<KeyPairHedera>(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize());
|
||||
}
|
||||
|
||||
bool CryptoKey::changeEncryption(Poco::AutoPtr<controller::User> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
#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 HederaAccount;
|
||||
|
||||
class CryptoKey : public TableControllerBase, public NotificationList
|
||||
{
|
||||
friend HederaAccount;
|
||||
public:
|
||||
|
||||
~CryptoKey();
|
||||
|
||||
static Poco::AutoPtr<CryptoKey> create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user, bool saveEncrypted = true);
|
||||
|
||||
//! if returned ptr is NULL, dataset not found
|
||||
static Poco::AutoPtr<CryptoKey> load(int id);
|
||||
static Poco::AutoPtr<CryptoKey> load(MemoryBin* publicKey);
|
||||
static Poco::AutoPtr<CryptoKey> load(const unsigned char* publicKey, size_t size);
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
inline Poco::AutoPtr<model::table::CryptoKey> getModel() { return _getModel<model::table::CryptoKey>(); }
|
||||
inline const model::table::CryptoKey* getModel() const { return _getModel<model::table::CryptoKey>(); }
|
||||
|
||||
std::unique_ptr<KeyPairHedera> getKeyPair(Poco::AutoPtr<controller::User> user) const;
|
||||
std::unique_ptr<KeyPairHedera> getKeyPair() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool changeEncryption(Poco::AutoPtr<controller::User> user);
|
||||
CryptoKey(model::table::CryptoKey* dbModel);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE
|
||||
@ -1,294 +0,0 @@
|
||||
|
||||
#include "HederaAccount.h"
|
||||
#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)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
|
||||
HederaAccount::~HederaAccount()
|
||||
{
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, ServerConfig::HederaNetworkType type/* = HEDERA_MAINNET*/)
|
||||
{
|
||||
auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance, type);
|
||||
auto group = new HederaAccount(db);
|
||||
return Poco::AutoPtr<HederaAccount>(group);
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> HederaAccount::load(const std::string& fieldName, int fieldValue)
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
auto hedera_account_list = db->loadFromDB<int, model::table::HederaAccountTuple>(fieldName, fieldValue, 2);
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> resultVector;
|
||||
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);
|
||||
resultVector.push_back(hedera_account);
|
||||
}
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::load(int id)
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
return new HederaAccount(db);
|
||||
}
|
||||
db->release();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<controller::HederaId> HederaAccount::getHederaId()
|
||||
{
|
||||
if (mHederaID.isNull()) {
|
||||
mHederaID = HederaId::load(getModel()->getAccountHederaId());
|
||||
}
|
||||
return mHederaID;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::load(Poco::AutoPtr<controller::HederaId> 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;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::pick(ServerConfig::HederaNetworkType networkType, bool encrypted/* = false*/, int user_id/* = 0*/)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
Poco::Tuple<int, int, int, int, Poco::UInt64, Poco::UInt64, Poco::UInt64, Poco::UInt64> result_tuple;
|
||||
int crypto_key_type = encrypted ? model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED : model::table::KEY_TYPE_ED25519_HEDERA_CLEAR;
|
||||
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_hedera_id) "
|
||||
<< "JOIN crypto_keys as k ON(k.id = account.account_key_id) "
|
||||
<< "WHERE account.network_type = ? "
|
||||
<< "AND k.crypto_key_type_id = ? ";
|
||||
|
||||
if (user_id > 0) {
|
||||
select << " AND account.user_id = ? ";
|
||||
}
|
||||
select << "ORDER BY RAND() LIMIT 1 "
|
||||
, into(result_tuple), use(network_type_int) , use(crypto_key_type);
|
||||
|
||||
if (user_id > 0) {
|
||||
select, use(user_id);
|
||||
}
|
||||
|
||||
try {
|
||||
select.executeAsync();
|
||||
select.wait();
|
||||
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
|
||||
);
|
||||
db->setID(result_tuple.get<0>());
|
||||
Poco::AutoPtr<HederaAccount> 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<HederaId> hedera_id(new HederaId(hedera_id_db));
|
||||
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));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> HederaAccount::listAll()
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
std::vector<model::table::HederaAccountTuple> group_list;
|
||||
// throw an unresolved external symbol error
|
||||
group_list = db->loadAllFromDB<model::table::HederaAccountTuple>();
|
||||
|
||||
// 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<Poco::AutoPtr<HederaAccount>> resultVector;
|
||||
|
||||
resultVector.reserve(group_list.size());
|
||||
for (auto it = group_list.begin(); it != group_list.end(); it++) {
|
||||
Poco::AutoPtr<HederaAccount> group_ptr(new HederaAccount(new model::table::HederaAccount(*it)));
|
||||
resultVector.push_back(group_ptr);
|
||||
}
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<controller::CryptoKey> HederaAccount::getCryptoKey() const
|
||||
{
|
||||
auto model = getModel();
|
||||
return controller::CryptoKey::load(model->getCryptoKeyId());
|
||||
}
|
||||
|
||||
bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr<controller::User> 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()));
|
||||
if (hedera_node.url == "") {
|
||||
addError(new Error("Hedera Node", "no hedera node found"));
|
||||
return false;
|
||||
}
|
||||
auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId());
|
||||
if (crypto_key.isNull()) {
|
||||
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) {
|
||||
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(getHederaId(), 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 {
|
||||
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response) && proto::OK == response.getResponseCode()) {
|
||||
account_model->updateIntoDB("balance", response.getAccountBalance());
|
||||
}
|
||||
else {
|
||||
addError(new Error("Hedera", "Hedera request failed"));
|
||||
addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode())));
|
||||
}
|
||||
//request.requestViaPHPRelay(query);
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data());
|
||||
}
|
||||
|
||||
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<controller::User> 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::unique_ptr<model::hedera::TransactionBody> HederaAccount::createTransactionBody()
|
||||
{
|
||||
auto account_model = getModel();
|
||||
auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType()));
|
||||
auto hedera_id = getHederaId();
|
||||
if (hedera_id.isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<model::hedera::TransactionBody>(mHederaID, hedera_node);
|
||||
}
|
||||
|
||||
|
||||
std::string HederaAccount::toShortSelectOptionName()
|
||||
{
|
||||
std::stringstream ss;
|
||||
auto model = getModel();
|
||||
ss << model::table::HederaAccount::hederaNetworkTypeToString((ServerConfig::HederaNetworkType)model->getNetworkType()) << " ";
|
||||
ss << getHederaId()->getModel()->toString() << " " << ((double)model->getBalance() / 100000000.0) << " Hbar";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE
|
||||
|
||||
#include "HederaId.h"
|
||||
#include "User.h"
|
||||
#include "../model/table/HederaAccount.h"
|
||||
|
||||
#include "../model/hedera/TransactionBody.h"
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
#include "CryptoKey.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaAccount : public TableControllerBase, public NotificationList
|
||||
{
|
||||
public:
|
||||
~HederaAccount();
|
||||
|
||||
static Poco::AutoPtr<HederaAccount> create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, ServerConfig::HederaNetworkType type = ServerConfig::HEDERA_MAINNET);
|
||||
|
||||
static std::vector<Poco::AutoPtr<HederaAccount>> load(const std::string& fieldName, int fieldValue);
|
||||
static Poco::AutoPtr<HederaAccount> load(int id);
|
||||
static Poco::AutoPtr<HederaAccount> load(Poco::AutoPtr<controller::HederaId> hederaId);
|
||||
static std::vector<Poco::AutoPtr<HederaAccount>> listAll();
|
||||
//! \brief for picking a account for paying transaction, mostly consensusSendMessage
|
||||
static Poco::AutoPtr<HederaAccount> pick(ServerConfig::HederaNetworkType networkType, bool encrypted = false, int user_id = 0);
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
std::string toShortSelectOptionName();
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaAccount> getModel() { return _getModel<model::table::HederaAccount>(); }
|
||||
inline const model::table::HederaAccount* getModel() const { return _getModel<model::table::HederaAccount>(); }
|
||||
|
||||
inline void setHederaId(Poco::AutoPtr<controller::HederaId> hederaId) { mHederaID = hederaId; }
|
||||
Poco::AutoPtr<controller::HederaId> getHederaId();
|
||||
|
||||
Poco::AutoPtr<controller::CryptoKey> getCryptoKey() const;
|
||||
|
||||
bool hederaAccountGetBalance(Poco::AutoPtr<controller::User> user);
|
||||
bool hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance);
|
||||
bool changeEncryption(Poco::AutoPtr<controller::User> user);
|
||||
|
||||
//! \brief create Transaction body with this hedera account as operator
|
||||
std::unique_ptr<model::hedera::TransactionBody> createTransactionBody();
|
||||
|
||||
protected:
|
||||
|
||||
HederaAccount(model::table::HederaAccount* dbModel);
|
||||
Poco::AutoPtr<HederaId> mHederaID;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE
|
||||
@ -1,127 +0,0 @@
|
||||
#include "HederaId.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace controller {
|
||||
|
||||
HederaId::HederaId(model::table::HederaId* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
|
||||
HederaId::~HederaId()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> 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<HederaId>(hedera_id);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaId::create(std::string hederaIdString)
|
||||
{
|
||||
auto sm = SessionManager::getInstance();
|
||||
if (!sm->isValid(hederaIdString, VALIDATE_HEDERA_ID)) {
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<std::string> number_strings;
|
||||
std::istringstream f(hederaIdString);
|
||||
std::string s;
|
||||
while (getline(f, s, '.')) {
|
||||
std::cout << s << std::endl;
|
||||
number_strings.push_back(s);
|
||||
}
|
||||
Poco::UInt64 numbers[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
unsigned long long temp_number;
|
||||
if (DataTypeConverter::NUMBER_PARSE_OKAY != DataTypeConverter::strToInt(number_strings[i], temp_number)) {
|
||||
return nullptr;
|
||||
}
|
||||
numbers[i] = temp_number;
|
||||
}
|
||||
auto db = new model::table::HederaId(numbers[0], numbers[1], numbers[2]);
|
||||
|
||||
auto hedera_id = new HederaId(db);
|
||||
return Poco::AutoPtr<HederaId>(hedera_id);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaId::load(int id)
|
||||
{
|
||||
auto db = new model::table::HederaId();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
auto cryptoKey = new HederaId(db);
|
||||
return Poco::AutoPtr<HederaId>(cryptoKey);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaId::find(int groupId, ServerConfig::HederaNetworkType networkType)
|
||||
{
|
||||
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(network_type_int);
|
||||
|
||||
try {
|
||||
select.executeAsync();
|
||||
select.wait();
|
||||
auto result_count = select.rowsExtracted();
|
||||
if (1 == result_count) {
|
||||
return new HederaId(new model::table::HederaId(result_tuple));
|
||||
}
|
||||
else if(result_count > 1) {
|
||||
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();
|
||||
protoAccountId->set_shardnum(model->getShardNum());
|
||||
protoAccountId->set_realmnum(model->getRealmNum());
|
||||
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();
|
||||
if (model->getID() > 0) return true;
|
||||
//std::vector<Tuple> loadFromDB(const std::vector<std::string>& fieldNames, const std::vector<WhereFieldType>& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0);
|
||||
model->isExistInDB();
|
||||
return model->getID() != 0;
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE
|
||||
|
||||
#include "../model/table/HederaId.h"
|
||||
#include "../model/table/HederaAccount.h"
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
|
||||
#include "proto/hedera/BasicTypes.pb.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaAccount;
|
||||
class HederaId : public TableControllerBase
|
||||
{
|
||||
friend HederaAccount;
|
||||
public:
|
||||
|
||||
~HederaId();
|
||||
|
||||
static Poco::AutoPtr<HederaId> create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num);
|
||||
static Poco::AutoPtr<HederaId> create(std::string hederaIdString);
|
||||
|
||||
static Poco::AutoPtr<HederaId> load(int id);
|
||||
//! \return hedera topic id for group and network type (should exist only one)
|
||||
static Poco::AutoPtr<HederaId> find(int groupId, ServerConfig::HederaNetworkType networkType);
|
||||
|
||||
bool isExistInDB();
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaId> getModel() { return _getModel<model::table::HederaId>(); }
|
||||
inline const model::table::HederaId* getModel() const { return _getModel<model::table::HederaId>(); }
|
||||
|
||||
void copyToProtoAccountId(proto::AccountID* protoAccountId) const;
|
||||
void copyToProtoTopicId(proto::TopicID* protoTopicId) const;
|
||||
|
||||
|
||||
protected:
|
||||
HederaId(model::table::HederaId* dbModel);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE
|
||||
@ -1,174 +0,0 @@
|
||||
#include "HederaRequest.h"
|
||||
#include "../proto/hedera/CryptoService.grpc.pb.h"
|
||||
#include "../proto/hedera/ConsensusService.grpc.pb.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpcpp/channel.h>
|
||||
#include <grpcpp/client_context.h>
|
||||
#include <grpcpp/create_channel.h>
|
||||
#include <chrono>
|
||||
|
||||
|
||||
HederaRequest::HederaRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaRequest::~HederaRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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(5000);
|
||||
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());
|
||||
|
||||
auto proto_response = response->getResponsePtr();
|
||||
auto connect_string = query->getConnectionString();
|
||||
|
||||
grpc::Status status;
|
||||
std::string queryName;
|
||||
|
||||
if (proto_query->has_cryptogetaccountbalance())
|
||||
{
|
||||
auto stub = proto::CryptoService::NewStub(channel);
|
||||
// crypto account get balance currently hasn't fees
|
||||
query->setResponseType(proto::ANSWER_ONLY);
|
||||
|
||||
queryName = "crypte get balance";
|
||||
status = stub->cryptoGetBalance(&context, *proto_query, proto_response);
|
||||
|
||||
}
|
||||
else if (proto_query->has_consensusgettopicinfo())
|
||||
{
|
||||
auto stub = proto::ConsensusService::NewStub(channel);
|
||||
|
||||
queryName = "consensus topic get info";
|
||||
status = stub->getTopicInfo(&context, *proto_query, proto_response);
|
||||
|
||||
}
|
||||
else if (proto_query->has_transactiongetreceipt()) {
|
||||
auto stub = proto::CryptoService::NewStub(channel);
|
||||
|
||||
queryName = "crypto transaction get receipt";
|
||||
status = stub->getTransactionReceipts(&context, *proto_query, proto_response);
|
||||
}
|
||||
else if (proto_query->has_transactiongetrecord()) {
|
||||
auto stub = proto::CryptoService::NewStub(channel);
|
||||
|
||||
queryName = "crypto transaction get record";
|
||||
status = stub->getTxRecordByTxID(&context, *proto_query, proto_response);
|
||||
|
||||
}
|
||||
else {
|
||||
addError(new Error("Hedera Request", "unknown or empty query"));
|
||||
return HEDERA_REQUEST_UNKNOWN_QUERY;
|
||||
}
|
||||
if (status.ok())
|
||||
{
|
||||
auto response_code = response->getResponseCode();
|
||||
if (response_code) {
|
||||
addError(new ParamError("Hedera Request", "precheck code: ", proto::ResponseCodeEnum_Name(response_code)));
|
||||
return HEDERA_REQUEST_PRECHECK_ERROR;
|
||||
}
|
||||
else {
|
||||
return HEDERA_REQUEST_RETURN_OK;
|
||||
}
|
||||
|
||||
}
|
||||
else if("" != queryName)
|
||||
{
|
||||
addError(new ParamError("Hedera Request", "query name: ", queryName));
|
||||
addError(new ParamError("Hedera Request", "error message: ", status.error_message()));
|
||||
addError(new ParamError("Hedera Request", "details: ", status.error_details()));
|
||||
return HEDERA_REQUEST_RETURN_ERROR;
|
||||
}
|
||||
return HEDERA_REQUEST_UNKNOWN_QUERY;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
task->setTransactionId(transaction->getTransactionId());
|
||||
if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type ||
|
||||
model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC == transaction_type) {
|
||||
auto stub = proto::ConsensusService::NewStub(channel);
|
||||
grpc::Status status;
|
||||
std::string service_name;
|
||||
if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type) {
|
||||
status = stub->submitMessage(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse());
|
||||
service_name = "submitMessage";
|
||||
}
|
||||
else if (model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC == transaction_type) {
|
||||
status = stub->createTopic(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse());
|
||||
service_name = "createTopic";
|
||||
}
|
||||
if (status.ok()) {
|
||||
return HEDERA_REQUEST_RETURN_OK;
|
||||
}
|
||||
else {
|
||||
addError(new ParamError("Hedera Request", "consensus service error message:", status.error_message()));
|
||||
addError(new ParamError("Hedera Request", "service name", service_name));
|
||||
addError(new ParamError("Hedera Request", "details: ", status.error_details()));
|
||||
return HEDERA_REQUEST_RETURN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
addError(new ParamError("Hedera Request", "not implementet or unknown transaction type", transaction_type));
|
||||
return HEDERA_REQUEST_UNKNOWN_TRANSACTION;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
#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"
|
||||
#include "../model/hedera/TransactionGetReceiptQuery.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_PRECHECK_ERROR,
|
||||
HEDERA_REQUEST_RETURN_ERROR,
|
||||
HEDERA_REQUEST_UNKNOWN_TRANSACTION,
|
||||
HEDERA_REQUEST_UNKNOWN_QUERY,
|
||||
HEDERA_REQUEST_CONNECT_ERROR
|
||||
};
|
||||
|
||||
// NodeServerConnection
|
||||
class HederaRequest : public NotificationList
|
||||
{
|
||||
public:
|
||||
HederaRequest();
|
||||
~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);
|
||||
//!
|
||||
//! \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);
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_
|
||||
//
|
||||
@ -1,235 +0,0 @@
|
||||
#include "HederaTopic.h"
|
||||
//#include "../model/hedera/Transaction.h"
|
||||
#include "HederaRequest.h"
|
||||
#include "../lib/Success.h"
|
||||
|
||||
#include "../model/hedera/ConsensusCreateTopic.h"
|
||||
#include "../model/hedera/Transaction.h"
|
||||
|
||||
#include "../SingletonManager/PendingTasksManager.h"
|
||||
|
||||
namespace controller {
|
||||
HederaTopic::HederaTopic(model::table::HederaTopic* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
HederaTopic::~HederaTopic()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTopic> 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<HederaTopic>(hedera_topic);
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaTopic>> HederaTopic::listAll()
|
||||
{
|
||||
auto db = new model::table::HederaTopic();
|
||||
std::vector<model::table::HederaTopicTuple> topic_list;
|
||||
// throw an unresolved external symbol error
|
||||
topic_list = db->loadAllFromDB<model::table::HederaTopicTuple>();
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaTopic>> resultVector;
|
||||
|
||||
resultVector.reserve(topic_list.size());
|
||||
for (auto it = topic_list.begin(); it != topic_list.end(); it++) {
|
||||
Poco::AutoPtr<HederaTopic> topic_ptr(new HederaTopic(new model::table::HederaTopic(*it)));
|
||||
resultVector.push_back(topic_ptr);
|
||||
}
|
||||
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTopic> HederaTopic::load(int id)
|
||||
{
|
||||
auto db = new model::table::HederaTopic;
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
return new HederaTopic(db);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaTopic::getTopicHederaId()
|
||||
{
|
||||
if (mTopicHederaId.isNull()) {
|
||||
mTopicHederaId = HederaId::load(getModel()->getTopicHederaId());
|
||||
}
|
||||
return mTopicHederaId;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaTopic::getAutoRenewAccount()
|
||||
{
|
||||
if (mAutoRenewAccount.isNull()) {
|
||||
mAutoRenewAccount = HederaAccount::load(getModel()->getAutoRenewAccountId());
|
||||
}
|
||||
return mAutoRenewAccount;
|
||||
}
|
||||
|
||||
bool HederaTopic::getTopicInfosFromHedera(Poco::AutoPtr<controller::HederaId> topicHederaId, Poco::AutoPtr<User> user, model::hedera::Response& response)
|
||||
{
|
||||
auto payer_account = controller::HederaAccount::pick(ServerConfig::g_HederaNetworkType);
|
||||
auto node_server = NodeServer::pick(payer_account->getModel()->getNetworkType(), getModel()->getGroupId());
|
||||
|
||||
if (topicHederaId.isNull()) {
|
||||
addError(new Error("Hedera Topic", "no hedera topic id exist"));
|
||||
return false;
|
||||
}
|
||||
auto query = model::hedera::Query::getTopicInfo(topicHederaId, payer_account->getHederaId(), node_server);
|
||||
query->setResponseType(proto::COST_ANSWER);
|
||||
HederaRequest request;
|
||||
query->sign(payer_account->getCryptoKey()->getKeyPair(user));
|
||||
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response)) {
|
||||
auto queryCost = response.getQueryCost();
|
||||
printf("query cost: %d\n", queryCost);
|
||||
|
||||
query->setTransactionFee(queryCost);
|
||||
query->setResponseType(proto::ANSWER_ONLY);
|
||||
query->sign(payer_account->getCryptoKey()->getKeyPair(user));
|
||||
|
||||
|
||||
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
addError(new Error("Hedera Query", "Error by query for consensus get topic info"));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
addError(new Error("Hedera Query", "Error by getting costs for consensus get topic info"));
|
||||
}
|
||||
getErrors(&request);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool HederaTopic::updateWithGetTopicInfos(Poco::AutoPtr<User> user)
|
||||
{
|
||||
|
||||
model::hedera::Response response;
|
||||
if (!getTopicInfosFromHedera(getTopicHederaId(), user, response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto consensus_topic_info = response.getConsensusTopicInfo();
|
||||
//addNotification(new ParamSuccess("consensus get topic info", "memo: ", consensus_topic_info->getMemo()));
|
||||
//addNotification(new ParamSuccess("consensus get topic info", "string: ", consensus_topic_info->toStringHtml()));
|
||||
auto model = getModel();
|
||||
model->setAutoRenewPeriod(consensus_topic_info->getAutoRenewPeriod().seconds());
|
||||
model->setCurrentTimeout(consensus_topic_info->getExpirationTime());
|
||||
model->setSequeceNumber(consensus_topic_info->getSequenceNumber());
|
||||
|
||||
|
||||
std::string fieldNames[] = { "auto_renew_period", "current_timeout", "sequence_number" };
|
||||
if (model->updateIntoDB(
|
||||
fieldNames,
|
||||
model->getAutoRenewPeriod(),
|
||||
model->getCurrentTimeout(),
|
||||
model->getSequenceNumber()
|
||||
) > 1) {
|
||||
addError(new Error("DB", "error saving changes in DB"));
|
||||
getErrors(model);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTopic> HederaTopic::loadFromHedera(Poco::AutoPtr<controller::HederaId> hederaId, Poco::UInt32 groupId, Poco::AutoPtr<User> user)
|
||||
{
|
||||
auto db = new model::table::HederaTopic();
|
||||
auto hedera_topic = new HederaTopic(db);
|
||||
|
||||
model::hedera::Response response;
|
||||
if (!hedera_topic->getTopicInfosFromHedera(hederaId, user, response)) {
|
||||
delete hedera_topic;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto consensus_topic_info = response.getConsensusTopicInfo();
|
||||
//addNotification(new ParamSuccess("consensus get topic info", "memo: ", consensus_topic_info->getMemo()));
|
||||
//addNotification(new ParamSuccess("consensus get topic info", "string: ", consensus_topic_info->toStringHtml()));
|
||||
auto group_name = consensus_topic_info->getMemo();
|
||||
auto groups = controller::Group::load(group_name);
|
||||
db->setTopicHederaID(hederaId->getModel()->getID());
|
||||
db->setName(group_name);
|
||||
if (1 == groups.size()) {
|
||||
db->setGroupId(groups[0]->getModel()->getID());
|
||||
}
|
||||
else if (groupId > 0) {
|
||||
db->setGroupId(groupId);
|
||||
}
|
||||
db->setAutoRenewPeriod(consensus_topic_info->getAutoRenewPeriod().seconds());
|
||||
db->setCurrentTimeout(consensus_topic_info->getExpirationTime());
|
||||
db->setSequeceNumber(consensus_topic_info->getSequenceNumber());
|
||||
|
||||
return Poco::AutoPtr<HederaTopic>(hedera_topic);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTask> HederaTopic::createTopic(Poco::AutoPtr<controller::HederaAccount> operatorAccount, Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
static const char* function_name = "HederaTopic::createTopic";
|
||||
printf("[HederaTopic::createTopic]\n");
|
||||
auto model = getModel();
|
||||
if (!model->getID()) {
|
||||
addError(new Error(function_name, "no db entry for topic created, id is missing"));
|
||||
return nullptr;
|
||||
}
|
||||
Poco::AutoPtr<controller::HederaId> autoRenewAccountId(nullptr);
|
||||
if (model->getAutoRenewAccountId()) {
|
||||
//autoRenewAccountId = controller::HederaId::load(model->getAutoRenewAccountId());
|
||||
}
|
||||
model::hedera::ConsensusCreateTopic hederaCreateTopic(autoRenewAccountId, model->getAutoRenewPeriod());
|
||||
auto hederaTransactionBody = operatorAccount->createTransactionBody();
|
||||
if (model->getName() != "") {
|
||||
hederaCreateTopic.setMemo(model->getName());
|
||||
}
|
||||
if (!hederaTransactionBody->setCreateTopic(hederaCreateTopic)) {
|
||||
addError(new Error(function_name, "error validating create topic transaction"));
|
||||
return nullptr;
|
||||
}
|
||||
model::hedera::Transaction hederaTransaction;
|
||||
if (!hederaTransaction.sign(operatorAccount->getCryptoKey()->getKeyPair(user), std::move(hederaTransactionBody))) {
|
||||
addError(new Error(function_name, "error signing hedera transaction"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto proto_transaction = hederaTransaction.getTransaction();
|
||||
|
||||
|
||||
Poco::AutoPtr<HederaTask> receiptTask(new HederaTask(&hederaTransaction));
|
||||
auto receipt_task_model = receiptTask->getModel();
|
||||
receipt_task_model->setParentPendingTaskId(model->getID());
|
||||
receipt_task_model->setUserId(user->getModel()->getID());
|
||||
|
||||
HederaRequest request;
|
||||
printf("[HederaTopic::createTopic] before calling request\n");
|
||||
auto result = request.request(&hederaTransaction, receiptTask.get());
|
||||
if (HEDERA_REQUEST_RETURN_OK == result) {
|
||||
if (proto::OK == receiptTask->getTransactionResponse()->getPrecheckCode()) {
|
||||
auto pt = PendingTasksManager::getInstance();
|
||||
printf("[HederaTopic::createTopic] before add task\n");
|
||||
pt->addTask(receiptTask);
|
||||
printf("[HederaTopic::createTopic] before start timer\n");
|
||||
receiptTask->startTimer();
|
||||
return receiptTask;
|
||||
}
|
||||
else {
|
||||
addError(new ParamError(function_name, "precheck code error", receiptTask->getTransactionResponse()->getPrecheckCodeString()));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
addError(new Error(function_name, "error in hedera request"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
#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"
|
||||
#include "../model/hedera/Response.h"
|
||||
#include "HederaId.h"
|
||||
#include "HederaAccount.h"
|
||||
|
||||
#include "../tasks/HederaTask.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaTopic : public TableControllerBase, public NotificationList
|
||||
{
|
||||
public:
|
||||
|
||||
~HederaTopic();
|
||||
|
||||
static Poco::AutoPtr<HederaTopic> create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId);
|
||||
static Poco::AutoPtr<HederaTopic> loadFromHedera(Poco::AutoPtr<controller::HederaId> hederaId, Poco::UInt32 groupId, Poco::AutoPtr<User> user);
|
||||
static std::vector<Poco::AutoPtr<HederaTopic>> listAll();
|
||||
static Poco::AutoPtr<HederaTopic> load(int id);
|
||||
|
||||
|
||||
bool updateWithGetTopicInfos(Poco::AutoPtr<User> user);
|
||||
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
Poco::AutoPtr<HederaId> getTopicHederaId();
|
||||
Poco::AutoPtr<HederaAccount> getAutoRenewAccount();
|
||||
|
||||
//! \brief hedera call to create a hedera topic
|
||||
Poco::AutoPtr<HederaTask> createTopic(Poco::AutoPtr<controller::HederaAccount> operatorAccount, Poco::AutoPtr<controller::User> user);
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaTopic> getModel() { return _getModel<model::table::HederaTopic>(); }
|
||||
|
||||
|
||||
protected:
|
||||
HederaTopic(model::table::HederaTopic* dbModel);
|
||||
|
||||
bool getTopicInfosFromHedera(Poco::AutoPtr<controller::HederaId> topicHederaId, Poco::AutoPtr<User> user, model::hedera::Response& response);
|
||||
|
||||
Poco::AutoPtr<HederaId> mTopicHederaId;
|
||||
Poco::AutoPtr<HederaAccount> mAutoRenewAccount;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H
|
||||
@ -1,208 +0,0 @@
|
||||
#include "NodeServer.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/ConnectionManager.h"
|
||||
#include "../SingletonManager/CronManager.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);
|
||||
}
|
||||
|
||||
std::string NodeServerConnection::getUri() const
|
||||
{
|
||||
std::string protocol;
|
||||
g_filterHttp.extract(url, protocol);
|
||||
return url.substr(protocol.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
NodeServer::NodeServer(model::table::NodeServer* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
if (model::table::NODE_SERVER_GRADIDO_COMMUNITY == dbModel->getNodeServerType()) {
|
||||
CronManager::getInstance()->addNodeServerToPing(Poco::AutoPtr<controller::NodeServer>(this, true));
|
||||
}
|
||||
}
|
||||
|
||||
NodeServer::~NodeServer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool NodeServer::deleteFromDB()
|
||||
{
|
||||
auto result = mDBModel->deleteFromDB();
|
||||
if (result && model::table::NODE_SERVER_GRADIDO_COMMUNITY == getModel()->getNodeServerType()) {
|
||||
CronManager::getInstance()->removeNodeServerToPing(Poco::AutoPtr<controller::NodeServer>(this, true));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<NodeServer> 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<NodeServer>(group);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<NodeServer> NodeServer::load(int id)
|
||||
{
|
||||
auto db = new model::table::NodeServer();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
return new NodeServer(db);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<NodeServer>> NodeServer::load(model::table::NodeServerType type, int group_id/* = 0*/)
|
||||
{
|
||||
auto db = new model::table::NodeServer();
|
||||
std::vector<model::table::NodeServerTuple> 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<model::table::NodeServerType, model::table::NodeServerTuple>("server_type", type, 4);
|
||||
}
|
||||
else if (type == model::table::NODE_SERVER_GRADIDO_NODE || type == model::table::NODE_SERVER_GRADIDO_COMMUNITY)
|
||||
{
|
||||
if (group_id)
|
||||
{
|
||||
node_server_list = db->loadFromDB<int, model::table::NodeServerTuple>(
|
||||
{ "server_type", "group_id" },
|
||||
{ type, group_id },
|
||||
model::table::MYSQL_CONDITION_AND
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
node_server_list = db->loadFromDB<int, model::table::NodeServerTuple >("server_type", type, 4);
|
||||
}
|
||||
}
|
||||
//auto node_server_list = db->loadFromDB<std::string, model::table::NodeServerTuple>("alias", alias, 0);
|
||||
|
||||
std::vector<Poco::AutoPtr<NodeServer>> 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(ServerConfig::HederaNetworkType type, int group_id /*= 0*/)
|
||||
{
|
||||
model::table::NodeServerType node_server_type = model::table::NODE_SERVER_NONE;
|
||||
if (ServerConfig::HEDERA_MAINNET) node_server_type = model::table::NODE_SERVER_HEDERA_MAINNET_NODE;
|
||||
else if (ServerConfig::HEDERA_TESTNET) node_server_type = model::table::NODE_SERVER_HEDERA_TESTNET_NODE;
|
||||
return pick(node_server_type, group_id);
|
||||
}
|
||||
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 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)) {
|
||||
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<Poco::AutoPtr<NodeServer>> NodeServer::listAll()
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
std::vector<NodeServerFullTuple> rows;
|
||||
// typedef Poco::Tuple<int, std::string, int, int, int, int, Poco::UInt64, Poco::UInt64, Poco::UInt64, Poco::DateTime> 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<Poco::AutoPtr<NodeServer>> 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<NodeServer> 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;
|
||||
|
||||
}
|
||||
|
||||
JsonRequest NodeServer::createJsonRequest()
|
||||
{
|
||||
auto model = getModel();
|
||||
NodeServerConnection connection(model->getUrl(), model->getPort());
|
||||
return JsonRequest(connection.getUri(), model->getPort());
|
||||
}
|
||||
|
||||
std::string NodeServer::getBaseUri()
|
||||
{
|
||||
auto model = getModel();
|
||||
NodeServerConnection connection(model->getUrl(), model->getPort());
|
||||
return connection.getUri();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
#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 "../lib/JsonRequest.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) {};
|
||||
|
||||
// with http:// or https://
|
||||
inline std::string getUrlWithPort() const { return url + ":" + std::to_string(port); }
|
||||
|
||||
// without http:// or https://
|
||||
std::string getUriWithPort() const;
|
||||
std::string getUri() const;
|
||||
|
||||
bool isValid() { return url != "" && port; }
|
||||
std::string url;
|
||||
int port;
|
||||
|
||||
Poco::AutoPtr<controller::HederaId> hederaId;
|
||||
};
|
||||
|
||||
typedef Poco::Tuple<int, std::string, int, int, int, int, Poco::UInt64, Poco::UInt64, Poco::UInt64, Poco::DateTime> NodeServerFullTuple;
|
||||
|
||||
class NodeServer : public TableControllerBase
|
||||
{
|
||||
public:
|
||||
|
||||
~NodeServer();
|
||||
|
||||
static Poco::AutoPtr<NodeServer> create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId);
|
||||
|
||||
//! \param group_id is zero take everyone
|
||||
static std::vector<Poco::AutoPtr<NodeServer>> load(model::table::NodeServerType type, int group_id = 0);
|
||||
static Poco::AutoPtr<NodeServer> load(int id);
|
||||
static std::vector<Poco::AutoPtr<NodeServer>> listAll();
|
||||
// pick server randomly
|
||||
static NodeServerConnection pick(ServerConfig::HederaNetworkType type, int group_id = 0);
|
||||
static NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0);
|
||||
bool deleteFromDB();
|
||||
|
||||
inline Poco::AutoPtr<model::table::NodeServer> getModel() { return _getModel<model::table::NodeServer>(); }
|
||||
|
||||
inline void setHederaId(Poco::AutoPtr<controller::HederaId> hederaId) { mHederaID = hederaId; }
|
||||
inline Poco::AutoPtr<controller::HederaId> getHederaId() { return mHederaID; }
|
||||
|
||||
std::string getBaseUri();
|
||||
JsonRequest createJsonRequest();
|
||||
protected:
|
||||
NodeServer(model::table::NodeServer* dbModel);
|
||||
Poco::AutoPtr<controller::HederaId> mHederaID;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE
|
||||
@ -1,7 +1,6 @@
|
||||
#include "PendingTask.h"
|
||||
|
||||
#include "../model/gradido/Transaction.h"
|
||||
#include "../tasks/HederaTask.h"
|
||||
|
||||
#include "../SingletonManager/PendingTasksManager.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
@ -37,7 +36,7 @@ namespace controller {
|
||||
resultVector.push_back(loadCorrectDerivedClass(new model::table::PendingTask(*it)));
|
||||
}
|
||||
return resultVector;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -57,9 +56,7 @@ namespace controller {
|
||||
if (dbModel->isGradidoTransaction()) {
|
||||
return model::gradido::Transaction::load(dbModel);
|
||||
}
|
||||
else if (dbModel->isGradidoTransaction()) {
|
||||
return HederaTask::load(dbModel);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -70,7 +67,7 @@ namespace controller {
|
||||
// throw an unresolved external symbol error
|
||||
task_list = db->loadAllFromDB<model::table::PendingTaskTuple>();
|
||||
|
||||
|
||||
|
||||
//*/ //work around end
|
||||
std::vector<Poco::AutoPtr<PendingTask>> resultVector;
|
||||
|
||||
@ -85,7 +82,7 @@ namespace controller {
|
||||
bool PendingTask::deleteFromDB()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
auto result = mDBModel->deleteFromDB();
|
||||
auto result = mDBModel->deleteFromDB();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -109,7 +106,7 @@ namespace controller {
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
static const char* function_name = "PendingTask::startTimer";
|
||||
auto em = ErrorManager::getInstance();
|
||||
|
||||
|
||||
if (isTimeoutTask()) {
|
||||
auto next_run_time = getNextRunTime();
|
||||
if (next_run_time >= Poco::DateTime()) {
|
||||
@ -136,7 +133,7 @@ namespace controller {
|
||||
Poco::TimerCallback<PendingTask> callback(*this, &PendingTask::calledFromTimer);
|
||||
mTimer.start(callback);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void PendingTask::calledFromTimer(Poco::Timer& timer)
|
||||
{
|
||||
@ -205,4 +202,4 @@ namespace controller {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/SingletonTaskObserver.h"
|
||||
|
||||
#include "NodeServer.h"
|
||||
#include "Group.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
@ -24,7 +23,7 @@ namespace controller {
|
||||
: mPassword(nullptr), mGradidoKeyPair(nullptr), mCanDecryptPrivateKey(false), mGradidoCurrentBalance(0)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
|
||||
|
||||
}
|
||||
|
||||
User::~User()
|
||||
@ -49,20 +48,20 @@ namespace controller {
|
||||
auto user = new User(db);
|
||||
return Poco::AutoPtr<User>(user);
|
||||
}
|
||||
|
||||
|
||||
std::vector<User*> User::search(const std::string& searchString, const std::string& accountState /* = "all" */)
|
||||
{
|
||||
|
||||
|
||||
auto sm = SessionManager::getInstance();
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto db = new model::table::User();
|
||||
static const char* functionName = "User::search";
|
||||
|
||||
|
||||
std::string globalSearch = "%" + searchString + "%";
|
||||
|
||||
std::vector<model::table::UserTuple> resultFromDB;
|
||||
if (accountState == "email not activated") {
|
||||
|
||||
|
||||
std::vector<std::string> fieldNames = { "first_name", "last_name", "email", "email_checked" };
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
std::vector<model::table::UserTuple> results;
|
||||
@ -106,6 +105,12 @@ namespace controller {
|
||||
|
||||
}
|
||||
|
||||
bool User::isUsernameAlreadyUsed(const std::string& username)
|
||||
{
|
||||
auto db = getModel();
|
||||
return db->loadFromDB({ "username", "group_id" }, username, db->getGroupId(), model::table::MYSQL_CONDITION_AND) > 0;
|
||||
}
|
||||
|
||||
int User::load(const unsigned char* pubkey_array)
|
||||
{
|
||||
Poco::Data::BLOB pubkey(pubkey_array, 32);
|
||||
@ -117,6 +122,14 @@ namespace controller {
|
||||
Poco::Data::BLOB email_hash(*emailHash, crypto_generichash_BYTES);
|
||||
return getModel()->loadFromDB("email_hash", email_hash);
|
||||
}
|
||||
size_t User::load(const std::string& emailOrUsername)
|
||||
{
|
||||
auto model = getModel();
|
||||
if (1 == model->loadFromDB("email", emailOrUsername)) {
|
||||
return 1;
|
||||
}
|
||||
return model->loadFromDB("username", emailOrUsername);
|
||||
}
|
||||
Poco::AutoPtr<User> User::sload(int user_id)
|
||||
{
|
||||
auto db = new model::table::User();
|
||||
@ -127,7 +140,7 @@ namespace controller {
|
||||
auto user = new User(db);
|
||||
return Poco::AutoPtr<User>(user);
|
||||
}
|
||||
|
||||
|
||||
void User::reload()
|
||||
{
|
||||
getModel()->loadFromDB("id", getModel()->getID());
|
||||
@ -147,15 +160,15 @@ namespace controller {
|
||||
|
||||
auto pubkey = getModel()->getPublicKey();
|
||||
|
||||
if (pubkey)
|
||||
if (pubkey)
|
||||
{
|
||||
auto pubkeyHex = mm->getFreeMemory(65);
|
||||
memset(*pubkeyHex, 0, 65);
|
||||
sodium_bin2hex(*pubkeyHex, 65, pubkey, 32);
|
||||
mPublicHex = (char*)*pubkeyHex;
|
||||
mm->releaseMemory(pubkeyHex);
|
||||
mm->releaseMemory(pubkeyHex);
|
||||
}
|
||||
|
||||
|
||||
unlock();
|
||||
return mPublicHex;
|
||||
}
|
||||
@ -185,7 +198,7 @@ namespace controller {
|
||||
return 2;
|
||||
}
|
||||
auto observer = SingletonTaskObserver::getInstance();
|
||||
|
||||
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
assert(mPassword.isNull());
|
||||
|
||||
@ -201,7 +214,7 @@ namespace controller {
|
||||
|
||||
observer->removeTask(email_hash, TASK_OBSERVER_PASSWORD_CREATION);
|
||||
|
||||
if (authenticated_encryption->getKeyHashed() == model->getPasswordHashed())
|
||||
if (authenticated_encryption->getKeyHashed() == model->getPasswordHashed())
|
||||
{
|
||||
// printf("[User::login] password key hashed is the same as saved password hash\n");
|
||||
MemoryBin* clear_private_key = nullptr;
|
||||
@ -212,7 +225,7 @@ namespace controller {
|
||||
if (!model->hasPrivateKeyEncrypted()) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (SecretKeyCryptography::AUTH_DECRYPT_OK == authenticated_encryption->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) {
|
||||
if (mGradidoKeyPair) {
|
||||
@ -247,7 +260,7 @@ namespace controller {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// password didn't match
|
||||
//printf("password hashed key: %ull, model pwd hashed keys: %ull\n", authenticated_encryption->getKeyHashed(), model->getPasswordHashed());
|
||||
//printf("password: %d\n", (int)(mPassword.get()));
|
||||
@ -285,12 +298,12 @@ namespace controller {
|
||||
}
|
||||
|
||||
|
||||
int User::setNewPassword(Poco::AutoPtr<SecretKeyCryptography> passwd)
|
||||
int User::setNewPassword(Poco::AutoPtr<SecretKeyCryptography> passwd)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
auto model = getModel();
|
||||
|
||||
if (!mPassword.isNull() && !passwd.isNull())
|
||||
if (!mPassword.isNull() && !passwd.isNull())
|
||||
{
|
||||
// if keys matched
|
||||
if (mPassword->isTheSame(passwd)) {
|
||||
@ -301,16 +314,16 @@ namespace controller {
|
||||
//if (!mGradidoKeyPair) mGradidoKeyPair = new KeyPairEd25519;
|
||||
MemoryBin* clear_private_key = nullptr;
|
||||
if (SecretKeyCryptography::AUTH_DECRYPT_OK == mPassword->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) {
|
||||
if (mGradidoKeyPair && mGradidoKeyPair->isTheSame(clear_private_key) != 0)
|
||||
if (mGradidoKeyPair && mGradidoKeyPair->isTheSame(clear_private_key) != 0)
|
||||
{
|
||||
delete mGradidoKeyPair;
|
||||
delete mGradidoKeyPair;
|
||||
mGradidoKeyPair = nullptr;
|
||||
}
|
||||
if (!mGradidoKeyPair)
|
||||
if (!mGradidoKeyPair)
|
||||
{
|
||||
mGradidoKeyPair = new KeyPairEd25519(clear_private_key);
|
||||
}
|
||||
|
||||
|
||||
// check if saved pubkey and from private key extracted pubkey match
|
||||
if (*mGradidoKeyPair != model->getPublicKey()) {
|
||||
delete mGradidoKeyPair;
|
||||
@ -358,7 +371,7 @@ namespace controller {
|
||||
continue;
|
||||
}
|
||||
auto key_pair = user_backup->createGradidoKeyPair();
|
||||
|
||||
|
||||
if (key_pair->isTheSame(user_model->getPublicKey())) {
|
||||
if (createdKeyPair) {
|
||||
*createdKeyPair = key_pair;
|
||||
@ -425,7 +438,7 @@ namespace controller {
|
||||
<< "LEFT JOIN email_opt_in as v ON(u.id = v.user_id) "
|
||||
<< "where u.email_checked = ? "
|
||||
<< "AND v.resend_count <= ? "
|
||||
<< "ORDER BY u.id, v.created " ,
|
||||
<< "ORDER BY u.id, v.created " ,
|
||||
Poco::Data::Keywords::use(email_checked), Poco::Data::Keywords::use(resend_count), Poco::Data::Keywords::into(results)
|
||||
;
|
||||
int result_count = 0;
|
||||
@ -499,7 +512,7 @@ namespace controller {
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
std::vector<Poco::Tuple<int, std::string>> results;
|
||||
|
||||
|
||||
select << "select id, email from users "
|
||||
<< "where email_hash IS NULL "
|
||||
, Poco::Data::Keywords::into(results)
|
||||
@ -553,42 +566,25 @@ namespace controller {
|
||||
printf("[%s] return saved group base Url: %s\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
}
|
||||
|
||||
|
||||
auto model = getModel();
|
||||
if (!model->getGroupId()) {
|
||||
printf("[%s] return ServerConfig::g_php_serverPath because no group id\n", function_name);
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
auto servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_COMMUNITY, model->getGroupId());
|
||||
if (!servers.size()) {
|
||||
auto group = controller::Group::load(model->getGroupId());
|
||||
if (!group.isNull()) {
|
||||
auto group_model = group->getModel();
|
||||
if (ServerConfig::g_ServerSetupType == ServerConfig::SERVER_TYPE_TEST) {
|
||||
mGroupBaseUrl = "http://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
else {
|
||||
mGroupBaseUrl = "https://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
printf("[%s] return group base Url: %s from Group\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
}
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
if (servers.size() > 1) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new ParamError(function_name, "error, more than one community server found for group", model->getGroupId()));
|
||||
em->sendErrorsAsEmail();
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
if (ServerConfig::g_ServerSetupType == ServerConfig::SERVER_TYPE_TEST) {
|
||||
mGroupBaseUrl = "http://" + servers[0]->getBaseUri();
|
||||
}
|
||||
else {
|
||||
mGroupBaseUrl = "https://" + servers[0]->getBaseUri();
|
||||
}
|
||||
printf("[%s] return group base Url: %s from NodeServer\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
auto group = controller::Group::load(model->getGroupId());
|
||||
if (!group.isNull()) {
|
||||
auto group_model = group->getModel();
|
||||
if (ServerConfig::g_ServerSetupType == ServerConfig::SERVER_TYPE_TEST) {
|
||||
mGroupBaseUrl = "http://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
else {
|
||||
mGroupBaseUrl = "https://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
printf("[%s] return group base Url: %s from Group\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
}
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<controller::Group> User::getGroup()
|
||||
|
||||
@ -47,6 +47,8 @@ namespace controller {
|
||||
|
||||
static std::vector<User*> search(const std::string& searchString, const std::string& accountState = "all");
|
||||
|
||||
bool isUsernameAlreadyUsed(const std::string& username);
|
||||
|
||||
//! \brief go through whole db and search users with email_checked = false and schedule resend 7 days after email_opt_in created date
|
||||
//!
|
||||
//! Should be only called by server start, later it aren't necessary, because register function schedule resend tasks by himself.
|
||||
@ -68,7 +70,7 @@ namespace controller {
|
||||
//! \return 0 matching entry found
|
||||
int tryLoadPassphraseUserBackup(KeyPairEd25519** createdKeyPair = nullptr);
|
||||
|
||||
inline size_t load(const std::string& email) { return getModel()->loadFromDB("email", email); }
|
||||
size_t load(const std::string& emailOrUsername);
|
||||
//! \brief try to load user from db via user_id
|
||||
//! \return count of found rows, should be 1 or 0
|
||||
inline size_t load(int user_id) { return getModel()->loadFromDB("id", user_id); }
|
||||
|
||||
@ -19,17 +19,17 @@ namespace DataTypeConverter
|
||||
result = stoi(input);
|
||||
return NUMBER_PARSE_OKAY;
|
||||
}
|
||||
catch (const std::invalid_argument& ia)
|
||||
catch (const std::invalid_argument& ia)
|
||||
{
|
||||
printf("[strToInt] exception: invalid argument: %s\n", ia.what());
|
||||
return NUMBER_PARSE_INVALID_ARGUMENT;
|
||||
}
|
||||
catch (const std::out_of_range& oor)
|
||||
catch (const std::out_of_range& oor)
|
||||
{
|
||||
printf("[strToInt] exception: out or range: %s\n", oor.what());
|
||||
return NUMBER_PARSE_OUT_OF_RANGE;
|
||||
}
|
||||
catch (const std::logic_error & ler)
|
||||
catch (const std::logic_error & ler)
|
||||
{
|
||||
printf("[strToInt] exception: logical error: %s\n", ler.what());
|
||||
return NUMBER_PARSE_LOGIC_ERROR;
|
||||
@ -198,13 +198,13 @@ namespace DataTypeConverter
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::string binToBase64(const unsigned char* data, size_t size, int variant /*= sodium_base64_VARIANT_ORIGINAL*/)
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
|
||||
size_t encodedSize = sodium_base64_encoded_len(size, variant);
|
||||
auto base64 = mm->getFreeMemory(encodedSize);
|
||||
memset(*base64, 0, encodedSize);
|
||||
@ -295,12 +295,6 @@ namespace DataTypeConverter
|
||||
return result;
|
||||
}
|
||||
|
||||
Poco::Timestamp convertFromProtoTimestamp(const proto::Timestamp& timestamp)
|
||||
{
|
||||
// microseconds
|
||||
google::protobuf::int64 microseconds = timestamp.seconds() * (google::protobuf::int64)10e5 + (google::protobuf::int64)(timestamp.nanos()) / (google::protobuf::int64)10e2;
|
||||
return microseconds;
|
||||
}
|
||||
|
||||
Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp)
|
||||
{
|
||||
@ -309,13 +303,6 @@ namespace DataTypeConverter
|
||||
return microseconds;
|
||||
}
|
||||
|
||||
void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp)
|
||||
{
|
||||
auto microsecondsTotal = pocoTimestamp.epochMicroseconds();
|
||||
auto secondsTotal = pocoTimestamp.epochTime();
|
||||
protoTimestamp->set_seconds(secondsTotal);
|
||||
protoTimestamp->set_nanos((microsecondsTotal - secondsTotal * pocoTimestamp.resolution()) * 1000);
|
||||
}
|
||||
|
||||
void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::gradido::Timestamp* protoTimestamp)
|
||||
{
|
||||
@ -333,11 +320,6 @@ namespace DataTypeConverter
|
||||
}
|
||||
|
||||
|
||||
Poco::Timespan convertFromProtoDuration(const proto::Duration& duration)
|
||||
{
|
||||
return Poco::Timespan(duration.seconds(), 0);
|
||||
}
|
||||
|
||||
int replaceBase64WithHex(Poco::JSON::Object::Ptr json)
|
||||
{
|
||||
//g_rexExpBase64
|
||||
@ -356,7 +338,7 @@ namespace DataTypeConverter
|
||||
count_replacements += replaceBase64WithHex(local_json);
|
||||
json->set(it->first, local_json);
|
||||
}
|
||||
else if (it->second.isString())
|
||||
else if (it->second.isString())
|
||||
{
|
||||
if (it->first == "amount") continue;
|
||||
auto field_value = it->second.extract<std::string>();
|
||||
@ -383,7 +365,7 @@ namespace DataTypeConverter
|
||||
for (Poco::JSON::Array::ValueVec::const_iterator it = json->begin(); it != json->end(); it++)
|
||||
{
|
||||
if (json->isObject(it)) {
|
||||
|
||||
|
||||
auto local_json = it->extract<Poco::JSON::Object::Ptr>();
|
||||
count_replacements += replaceBase64WithHex(local_json);
|
||||
json->set(count, local_json);
|
||||
@ -414,14 +396,14 @@ namespace DataTypeConverter
|
||||
|
||||
std::string replaceNewLineWithBr(std::string& in)
|
||||
{
|
||||
|
||||
|
||||
std::string::size_type pos = 0; // Must initialize
|
||||
while ((pos = in.find("\r\n", pos)) != std::string::npos) {
|
||||
in.replace(pos, 2, "<br>");
|
||||
}
|
||||
pos = 0;
|
||||
while ((pos = in.find("\n", pos)) != std::string::npos) {
|
||||
in.replace(pos, 1, "<br>");
|
||||
in.replace(pos, 1, "<br>");
|
||||
}
|
||||
pos = 0;
|
||||
while ((pos = in.find(" ", pos)) != std::string::npos) {
|
||||
@ -429,4 +411,4 @@ namespace DataTypeConverter
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,6 @@
|
||||
#include "Poco/JSON/Array.h"
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
|
||||
#include "proto/hedera/Timestamp.pb.h"
|
||||
#include "proto/hedera/Duration.pb.h"
|
||||
#include "proto/gradido/BasicTypes.pb.h"
|
||||
|
||||
#include "sodium.h"
|
||||
@ -58,15 +56,12 @@ namespace DataTypeConverter {
|
||||
//! \brief convert duration in string showing seconds, minutes, hours or days
|
||||
std::string convertTimespanToLocalizedString(Poco::Timespan duration, LanguageCatalog* lang);
|
||||
|
||||
Poco::Timestamp convertFromProtoTimestamp(const proto::Timestamp& timestamp);
|
||||
Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp);
|
||||
void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp);
|
||||
void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::gradido::Timestamp* protoTimestamp);
|
||||
Poco::Timestamp convertFromProtoTimestampSeconds(const proto::gradido::TimestampSeconds& timestampSeconds);
|
||||
inline void convertToProtoTimestampSeconds(const Poco::Timestamp pocoTimestamp, proto::gradido::TimestampSeconds* protoTimestampSeconds) {
|
||||
protoTimestampSeconds->set_seconds(pocoTimestamp.epochTime());
|
||||
}
|
||||
Poco::Timespan convertFromProtoDuration(const proto::Duration& duration);
|
||||
|
||||
//! \brief go through json object and replace every string entry in base64 format into hex format
|
||||
//! \return count of replaced strings
|
||||
|
||||
@ -7,6 +7,12 @@ Error::Error(const char* functionName, const char* message)
|
||||
|
||||
}
|
||||
|
||||
Error::Error(const char* functionName, const std::string& message)
|
||||
: Notification(functionName, message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Error::~Error()
|
||||
{
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ class Error : public Notification
|
||||
{
|
||||
public:
|
||||
Error(const char* functionName, const char* message);
|
||||
Error(const char* functionName, const std::string& message);
|
||||
~Error();
|
||||
|
||||
const char* getFunctionName() { return mFunctionName.data(); }
|
||||
@ -39,6 +40,8 @@ public:
|
||||
: Error(functionName, message), mParam(param) {}
|
||||
ParamError(const char* functionName, const char* message, const std::string& param)
|
||||
: Error(functionName, message), mParam(param) {}
|
||||
ParamError(const char* functionName, const std::string& message, const std::string& param)
|
||||
: Error(functionName, message), mParam(param) {}
|
||||
|
||||
ParamError(const char* functioName, const char* message, int param)
|
||||
: Error(functioName, message) {
|
||||
|
||||
@ -4,4 +4,10 @@ Notification::Notification(const char* functionName, const char* message)
|
||||
: mFunctionName(functionName), mMessage(message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Notification::Notification(const char* functionName, const std::string& message)
|
||||
: mFunctionName(functionName), mMessage(message)
|
||||
{
|
||||
|
||||
}
|
||||
@ -7,6 +7,7 @@ class Notification
|
||||
{
|
||||
public:
|
||||
Notification(const char* functionName, const char* message);
|
||||
Notification(const char* functionName, const std::string& message);
|
||||
|
||||
const char* getFunctionName() { return mFunctionName.data(); }
|
||||
const char* getMessage() { return mMessage.data(); }
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "model/table/EmailOptIn.h"
|
||||
|
||||
#include "Poco/DateTimeParser.h"
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#ifndef _TEST_BUILD
|
||||
|
||||
@ -52,18 +51,16 @@ int main(int argc, char** argv)
|
||||
return -3;
|
||||
}
|
||||
printf("[Gradido_LoginServer::main] passed important tests\n");
|
||||
grpc_init();
|
||||
|
||||
Gradido_LoginServer app;
|
||||
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
|
||||
#endif
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
|
||||
#include "../tasks/PrepareEmailTask.h"
|
||||
#include "../tasks/SendEmailTask.h"
|
||||
#include "../tasks/SigningTransaction.h"
|
||||
#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h"
|
||||
#include "../tasks/VerificationEmailResendTask.h"
|
||||
|
||||
@ -53,8 +52,8 @@ Session::~Session()
|
||||
unlock();
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//printf("[Session::~Session] finished \n");
|
||||
}
|
||||
|
||||
@ -70,24 +69,21 @@ void Session::reset()
|
||||
// watch out
|
||||
//updateTimeout();
|
||||
mLastActivity = Poco::DateTime();
|
||||
|
||||
|
||||
mState = SESSION_STATE_EMPTY;
|
||||
|
||||
|
||||
mPassphrase = "";
|
||||
mLastExternReferer = "";
|
||||
mClientLoginIP = Poco::Net::IPAddress();
|
||||
unlock();
|
||||
|
||||
// reset transactions
|
||||
mCurrentActiveProcessingTransaction = nullptr;
|
||||
mProcessingTransactions.clear();
|
||||
|
||||
//printf("[Session::reset] finished\n");
|
||||
}
|
||||
|
||||
int Session::isActive()
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
try {
|
||||
mWorkMutex.tryLock(100);
|
||||
}
|
||||
@ -95,7 +91,7 @@ int Session::isActive()
|
||||
return -1;
|
||||
}
|
||||
ret = (int)mActive;
|
||||
unlock();
|
||||
unlock();
|
||||
return ret;
|
||||
|
||||
}
|
||||
@ -108,21 +104,21 @@ bool Session::isDeadLocked()
|
||||
return false;
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Session::setActive(bool active)
|
||||
{
|
||||
{
|
||||
try {
|
||||
mWorkMutex.tryLock(100);
|
||||
}
|
||||
catch (Poco::TimeoutException &ex) {
|
||||
return false;
|
||||
}
|
||||
mActive = active;
|
||||
unlock();
|
||||
mActive = active;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -187,13 +183,13 @@ bool Session::adminCreateUser(const std::string& first_name, const std::string&
|
||||
addError(new Error(gettext("Email Verification Code"), gettext("Fehler beim speichern!")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EmailManager::getInstance()->addEmail(new model::Email(email_verification_code, newUser, model::EMAIL_ADMIN_USER_VERIFICATION_CODE));
|
||||
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
mEmailVerificationCodeObject = email_verification_code;
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -223,7 +219,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string&
|
||||
addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!sm->checkPwdValidation(password, this, mLanguageCatalog)) {
|
||||
return false;
|
||||
}
|
||||
@ -247,7 +243,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string&
|
||||
auto user_model = mNewUser->getModel();
|
||||
user_model->insertIntoDB(true);
|
||||
auto user_id = user_model->getID();
|
||||
|
||||
|
||||
// one retry in case of connection error
|
||||
if (!user_id) {
|
||||
user_model->insertIntoDB(true);
|
||||
@ -317,17 +313,17 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
// new mutex, will replace the Poco Mutex complete in the future
|
||||
std::unique_lock<std::shared_mutex> _lock_shared(mSharedMutex);
|
||||
Profiler usedTime;
|
||||
|
||||
|
||||
auto em = ErrorManager::getInstance();
|
||||
if (mEmailVerificationCodeObject.isNull()) {
|
||||
em->addError(new Error(funcName, "email verification object is zero"));
|
||||
em->sendErrorsAsEmail();
|
||||
|
||||
|
||||
return -2;
|
||||
}
|
||||
auto email_verification_code_model = mEmailVerificationCodeObject->getModel();
|
||||
assert(email_verification_code_model);
|
||||
if(email_verification_code_model->getCode() == emailVerificationCode)
|
||||
if(email_verification_code_model->getCode() == emailVerificationCode)
|
||||
{
|
||||
// load correct user from db
|
||||
if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getModel()->getID() != email_verification_code_model->getUserId()) {
|
||||
@ -335,7 +331,7 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
if (1 != mNewUser->load(email_verification_code_model->getUserId())) {
|
||||
em->addError(new ParamError(funcName, "user load didn't return 1 with user_id ", email_verification_code_model->getUserId()));
|
||||
em->sendErrorsAsEmail();
|
||||
|
||||
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@ -344,14 +340,14 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
assert(user_model);
|
||||
bool first_email_activation = false;
|
||||
auto verification_type = email_verification_code_model->getType();
|
||||
if (model::table::EMAIL_OPT_IN_REGISTER == verification_type ||
|
||||
if (model::table::EMAIL_OPT_IN_REGISTER == verification_type ||
|
||||
model::table::EMAIL_OPT_IN_EMPTY == verification_type ||
|
||||
model::table::EMAIL_OPT_IN_REGISTER_DIRECT == verification_type) {
|
||||
first_email_activation = true;
|
||||
}
|
||||
if (first_email_activation && user_model->isEmailChecked()) {
|
||||
addError(new Error(gettext("E-Mail Verification"), gettext("Du hast dein Konto bereits aktiviert!")), false);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (first_email_activation) {
|
||||
@ -363,13 +359,13 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
}
|
||||
|
||||
// no find all active sessions
|
||||
|
||||
|
||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (email_verification_code_model->getType() == model::table::EMAIL_OPT_IN_RESET_PASSWORD) {
|
||||
|
||||
|
||||
if (mEmailVerificationCodeObject->deleteFromDB()) {
|
||||
mEmailVerificationCodeObject.assign(nullptr);
|
||||
}
|
||||
@ -385,18 +381,18 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
|
||||
em->addError(new Error(funcName, "invalid code path"));
|
||||
em->sendErrorsAsEmail();
|
||||
|
||||
|
||||
return -2;
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
addError(new Error(gettext("E-Mail Verification"), gettext("Falscher Code für aktiven Login")));
|
||||
//printf("[%s] time: %s\n", funcName, usedTime.string().data());
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
//printf("[%s] time: %s\n", funcName, usedTime.string().data());
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -409,7 +405,7 @@ int Session::sendResetPasswordEmail(Poco::AutoPtr<controller::User> user, bool p
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
|
||||
// creating email verification code also for user without passphrase
|
||||
// first check if already exist
|
||||
// first check if already exist
|
||||
// check if email was already send shortly before
|
||||
bool frequent_resend = false;
|
||||
bool email_already_send = false;
|
||||
@ -450,7 +446,7 @@ int Session::sendResetPasswordEmail(Poco::AutoPtr<controller::User> user, bool p
|
||||
|
||||
int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, const Mnemonic* wordSource)
|
||||
{
|
||||
|
||||
|
||||
static const char* functionName = "Session::comparePassphraseWithSavedKeys";
|
||||
if (!wordSource) {
|
||||
addError(new Error(functionName, "wordSource is empty"));
|
||||
@ -495,137 +491,6 @@ int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Session::startProcessingTransaction(const std::string& proto_message_base64, bool autoSign/* = false*/)
|
||||
{
|
||||
static const char* funcName = "Session::startProcessingTransaction";
|
||||
lock(funcName);
|
||||
HASH hs = ProcessingTransaction::calculateHash(proto_message_base64);
|
||||
// check if it is already running or waiting
|
||||
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
|
||||
if (it->isNull()) {
|
||||
it = mProcessingTransactions.erase(it);
|
||||
}
|
||||
if (hs == (*it)->getHash()) {
|
||||
addError(new Error(funcName, "transaction already in list"));
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Languages lang = LANG_DE;
|
||||
if (!mNewUser.isNull()) {
|
||||
lang = LanguageManager::languageFromString(mNewUser->getModel()->getLanguageKey());
|
||||
}
|
||||
auto user_model = mNewUser->getModel();
|
||||
Poco::AutoPtr<ProcessingTransaction> processorTask(
|
||||
new ProcessingTransaction(
|
||||
proto_message_base64,
|
||||
DRMakeStringHash(user_model->getEmail().data()),
|
||||
lang
|
||||
)
|
||||
);
|
||||
if (autoSign && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) == ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) {
|
||||
if (processorTask->run() != 0) {
|
||||
getErrors(processorTask);
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
Poco::AutoPtr<SigningTransaction> signingTransaction(new SigningTransaction(processorTask, mNewUser));
|
||||
//signingTransaction->scheduleTask(signingTransaction);
|
||||
if (signingTransaction->run() != 0) {
|
||||
getErrors(signingTransaction);
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
processorTask->scheduleTask(processorTask);
|
||||
mProcessingTransactions.push_back(processorTask);
|
||||
}
|
||||
unlock();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<ProcessingTransaction> Session::getNextReadyTransaction(size_t* working/* = nullptr*/)
|
||||
{
|
||||
lock("Session::getNextReadyTransaction");
|
||||
if (working) {
|
||||
*working = 0;
|
||||
}
|
||||
else if (!mCurrentActiveProcessingTransaction.isNull())
|
||||
{
|
||||
unlock();
|
||||
return mCurrentActiveProcessingTransaction;
|
||||
}
|
||||
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
|
||||
if (working && !(*it)->isTaskFinished()) {
|
||||
(*working)++;
|
||||
}
|
||||
if (mCurrentActiveProcessingTransaction.isNull() && (*it)->isTaskFinished()) {
|
||||
if (!working) {
|
||||
mCurrentActiveProcessingTransaction = *it;
|
||||
unlock();
|
||||
return mCurrentActiveProcessingTransaction;
|
||||
}
|
||||
// no early exit
|
||||
else {
|
||||
mCurrentActiveProcessingTransaction = *it;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return mCurrentActiveProcessingTransaction;
|
||||
}
|
||||
|
||||
bool Session::finalizeTransaction(bool sign, bool reject)
|
||||
{
|
||||
int result = -1;
|
||||
lock("Session::finalizeTransaction");
|
||||
if (mCurrentActiveProcessingTransaction.isNull()) {
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
mProcessingTransactions.remove(mCurrentActiveProcessingTransaction);
|
||||
|
||||
if (!reject) {
|
||||
if (sign) {
|
||||
Poco::AutoPtr<SigningTransaction> signingTransaction(new SigningTransaction(mCurrentActiveProcessingTransaction, mNewUser));
|
||||
//signingTransaction->scheduleTask(signingTransaction);
|
||||
result = signingTransaction->run();
|
||||
}
|
||||
}
|
||||
mCurrentActiveProcessingTransaction.assign(nullptr);
|
||||
unlock();
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
size_t Session::getProcessingTransactionCount()
|
||||
{
|
||||
size_t count = 0;
|
||||
lock("Session::getProcessingTransactionCount");
|
||||
|
||||
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
|
||||
|
||||
(*it)->lock();
|
||||
if ((*it)->errorCount() > 0) {
|
||||
(*it)->sendErrorsAsEmail();
|
||||
(*it)->unlock();
|
||||
it = mProcessingTransactions.erase(it);
|
||||
if (it == mProcessingTransactions.end()) break;
|
||||
}
|
||||
else {
|
||||
(*it)->unlock();
|
||||
}
|
||||
|
||||
}
|
||||
count = mProcessingTransactions.size();
|
||||
unlock();
|
||||
return count;
|
||||
}
|
||||
|
||||
UserState Session::loadUser(const std::string& email, const std::string& password)
|
||||
{
|
||||
static const char* functionName = "Session::loadUser";
|
||||
@ -657,11 +522,11 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
}
|
||||
//printf("before get model\n");
|
||||
auto user_model = mNewUser->getModel();
|
||||
if (user_model && user_model->isDisabled()) {
|
||||
if (user_model && user_model->isDisabled()) {
|
||||
return USER_DISABLED;
|
||||
}
|
||||
if (mNewUser->getUserState() >= USER_LOADED_FROM_DB) {
|
||||
|
||||
|
||||
NotificationList pwd_errors;
|
||||
auto lm = LanguageManager::getInstance();
|
||||
auto lang_key = mNewUser->getModel()->getLanguageKey();
|
||||
@ -677,9 +542,9 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
|
||||
int loginResult = mNewUser->login(password);
|
||||
int exitCount = 0;
|
||||
if (loginResult == -3)
|
||||
if (loginResult == -3)
|
||||
{
|
||||
do
|
||||
do
|
||||
{
|
||||
Poco::Thread::sleep(100);
|
||||
loginResult = mNewUser->login(password);
|
||||
@ -702,7 +567,7 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
return USER_PASSWORD_ENCRYPTION_IN_PROCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (-1 == loginResult)
|
||||
{
|
||||
addError(new Error(functionName, "error in user data set, saved pubkey didn't match extracted pubkey from private key"));
|
||||
@ -711,7 +576,7 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
//unlock();
|
||||
//return USER_KEYS_DONT_MATCH;
|
||||
}
|
||||
if (0 == loginResult)
|
||||
if (0 == loginResult)
|
||||
{
|
||||
return USER_PASSWORD_INCORRECT;
|
||||
}
|
||||
@ -724,9 +589,9 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
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<KeyPairEd25519>((*it)->createGradidoKeyPair());
|
||||
if (key->isTheSame(user_model->getPublicKey()))
|
||||
if (key->isTheSame(user_model->getPublicKey()))
|
||||
{
|
||||
|
||||
|
||||
// set valid key pair
|
||||
if (1 == mNewUser->setGradidoKeyPair(key.release())) {
|
||||
// save new encrypted private key
|
||||
@ -742,7 +607,7 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime);
|
||||
@ -851,7 +716,7 @@ void Session::detectSessionState()
|
||||
else if (checkEmail != -1) {
|
||||
mEmailVerificationCodeObject = emailVerificationCodeObjects[checkEmail];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[Session::detectSessionState] exception: %s\n", ex.displayText().data());
|
||||
@ -864,13 +729,13 @@ void Session::detectSessionState()
|
||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
updateState(SESSION_STATE_USER_WRITTEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (USER_NO_KEYS == userState) {
|
||||
|
||||
|
||||
auto user_id = mNewUser->getModel()->getID();
|
||||
auto userBackups = controller::UserBackup::load(user_id);
|
||||
|
||||
@ -903,8 +768,8 @@ void Session::detectSessionState()
|
||||
auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(dbConnection);
|
||||
Poco::Nullable<Poco::Data::BLOB> passphrase;
|
||||
|
||||
select << "SELECT passphrase from user_backups where user_id = ?;",
|
||||
|
||||
select << "SELECT passphrase from user_backups where user_id = ?;",
|
||||
into(passphrase), use(user_id);
|
||||
try {
|
||||
if (select.execute() == 1 && !passphrase.isNull()) {
|
||||
@ -927,7 +792,7 @@ void Session::detectSessionState()
|
||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
updateState(SESSION_STATE_KEY_PAIR_WRITTEN);
|
||||
|
||||
if (resetPasswd != -1) {
|
||||
@ -945,14 +810,14 @@ Poco::Net::HTTPCookie Session::getLoginCookie()
|
||||
// keks.setHttpOnly();
|
||||
|
||||
keks.setPath("/");
|
||||
// send cookie only via https, on linux, except in test builds
|
||||
// send cookie only via https, on linux, except in test builds
|
||||
#ifndef WIN32
|
||||
if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType ||
|
||||
ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) {
|
||||
keks.setSecure(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return keks;
|
||||
}
|
||||
|
||||
@ -1024,7 +889,7 @@ const char* Session::translateSessionStateToString(SessionStates state)
|
||||
case SESSION_STATE_EMAIL_VERIFICATION_SEND: return "Verification E-Mail sended";
|
||||
case SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED: return "Verification Code checked";
|
||||
case SESSION_STATE_PASSPHRASE_GENERATED: return "Passphrase generated";
|
||||
case SESSION_STATE_PASSPHRASE_SHOWN: return "Passphrase shown";
|
||||
case SESSION_STATE_PASSPHRASE_SHOWN: return "Passphrase shown";
|
||||
case SESSION_STATE_PASSPHRASE_WRITTEN: return "Passphrase written";
|
||||
case SESSION_STATE_KEY_PAIR_GENERATED: return "Gradido Address created";
|
||||
case SESSION_STATE_KEY_PAIR_WRITTEN: return "Gradido Address saved";
|
||||
@ -1041,7 +906,7 @@ const char* Session::translateSessionStateToString(SessionStates state)
|
||||
bool Session::useOrGeneratePassphrase(const std::string& passphase)
|
||||
{
|
||||
if (passphase != "" && User::validatePassphrase(passphase)) {
|
||||
// passphrase is valid
|
||||
// passphrase is valid
|
||||
setPassphrase(passphase);
|
||||
updateState(SESSION_STATE_PASSPHRASE_SHOWN);
|
||||
return true;
|
||||
@ -1081,7 +946,7 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase)
|
||||
if (savePassphrase) {
|
||||
auto user_backup = controller::UserBackup::create(user_model->getID(), passphrase->getString(), mnemonic_type);
|
||||
// sync version
|
||||
//user_backup->getModel()->insertIntoDB(false);
|
||||
//user_backup->getModel()->insertIntoDB(false);
|
||||
|
||||
// async version
|
||||
UniLib::controller::TaskPtr save_user_backup_task = new model::table::ModelInsertTask(user_backup->getModel(), false, true);
|
||||
@ -1089,7 +954,7 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase)
|
||||
save_user_backup_task->scheduleTask(save_user_backup_task);
|
||||
}
|
||||
|
||||
// keys
|
||||
// keys
|
||||
auto gradido_key_pair = KeyPairEd25519::create(passphrase);
|
||||
auto set_key_result = mNewUser->setGradidoKeyPair(gradido_key_pair);
|
||||
size_t result_save_key = 0;
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "../controller/User.h"
|
||||
|
||||
#include "../lib/MultithreadContainer.h"
|
||||
#include "../tasks/ProcessingTransaction.h"
|
||||
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
|
||||
@ -83,7 +82,7 @@ public:
|
||||
// TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing
|
||||
UserState loadUser(const std::string& email, const std::string& password);
|
||||
bool ifUserExist(const std::string& email);
|
||||
|
||||
|
||||
bool deleteUser();
|
||||
|
||||
|
||||
@ -102,7 +101,7 @@ public:
|
||||
//! \return 2 = reset password email already shortly before
|
||||
//! \return 0 = ok
|
||||
int sendResetPasswordEmail(Poco::AutoPtr<controller::User> user, bool passphraseMemorized, const std::string &baseUrl);
|
||||
//
|
||||
//
|
||||
//! \return 0 = not the same
|
||||
//! \return 1 = same
|
||||
//! \return -1 = error
|
||||
@ -111,23 +110,23 @@ public:
|
||||
|
||||
Poco::Net::HTTPCookie getLoginCookie();
|
||||
|
||||
|
||||
|
||||
inline int getHandle() { return mHandleId; }
|
||||
|
||||
// ------------------------ Passphrase functions ----------------------------
|
||||
|
||||
|
||||
inline void setPassphrase(Poco::AutoPtr<Passphrase> passphrase) { mNewPassphrase = passphrase; }
|
||||
inline Poco::AutoPtr<Passphrase> getPassphrase() { return mNewPassphrase; }
|
||||
|
||||
inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; }
|
||||
|
||||
|
||||
inline const std::string& getOldPassphrase() { return mPassphrase; }
|
||||
|
||||
|
||||
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; }
|
||||
void reset();
|
||||
|
||||
@ -135,9 +134,9 @@ public:
|
||||
const char* getSessionStateString();
|
||||
inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; }
|
||||
|
||||
inline Poco::UInt64 getEmailVerificationCode() {
|
||||
inline Poco::UInt64 getEmailVerificationCode() {
|
||||
std::shared_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode();
|
||||
if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode();
|
||||
}
|
||||
inline void setEmailVerificationCodeObject(Poco::AutoPtr<controller::EmailVerificationCode> emailVerficationObject) {
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
@ -153,7 +152,7 @@ public:
|
||||
|
||||
//! \return -1 if session is locked
|
||||
//! \return 1 if session is active
|
||||
//! \return 0
|
||||
//! \return 0
|
||||
int isActive();
|
||||
//! \return false if session is locked
|
||||
bool setActive(bool active);
|
||||
@ -164,12 +163,6 @@ public:
|
||||
|
||||
// ------------------------ transactions functions ----------------------------
|
||||
|
||||
//! \return true if succeed
|
||||
bool startProcessingTransaction(const std::string& proto_message_base64, bool autoSign = false);
|
||||
//! \param working if set will filled with transaction running
|
||||
Poco::AutoPtr<ProcessingTransaction> getNextReadyTransaction(size_t* working = nullptr);
|
||||
bool finalizeTransaction(bool sign, bool reject);
|
||||
size_t getProcessingTransactionCount();
|
||||
|
||||
inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; }
|
||||
void setLanguage(Languages lang);
|
||||
@ -187,14 +180,14 @@ public:
|
||||
protected:
|
||||
void updateTimeout();
|
||||
inline void setHandle(int newHandle) { mHandleId = newHandle; }
|
||||
|
||||
|
||||
void detectSessionState();
|
||||
static const char* translateSessionStateToString(SessionStates state);
|
||||
|
||||
inline const std::string& getPassphrase() const { return mPassphrase; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
int mHandleId;
|
||||
Poco::AutoPtr<controller::User> mNewUser;
|
||||
std::string mPassphrase;
|
||||
@ -211,8 +204,6 @@ private:
|
||||
SessionStates mState;
|
||||
|
||||
bool mActive;
|
||||
std::list<Poco::AutoPtr<ProcessingTransaction>> mProcessingTransactions;
|
||||
Poco::AutoPtr<ProcessingTransaction> mCurrentActiveProcessingTransaction;
|
||||
|
||||
Poco::AutoPtr<LanguageCatalog> mLanguageCatalog;
|
||||
};
|
||||
|
||||
@ -2,21 +2,13 @@
|
||||
#include "../../SingletonManager/ErrorManager.h"
|
||||
#include "../../SingletonManager/PendingTasksManager.h"
|
||||
#include "../../SingletonManager/LanguageManager.h"
|
||||
#include "../../SingletonManager/CronManager.h"
|
||||
#include "../../ServerConfig.h"
|
||||
|
||||
#include "../../controller/HederaId.h"
|
||||
#include "../../controller/HederaAccount.h"
|
||||
#include "../../controller/HederaRequest.h"
|
||||
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
#include "../../lib/Profiler.h"
|
||||
#include "../../lib/JsonRequest.h"
|
||||
|
||||
#include "../hedera/Transaction.h"
|
||||
#include "../hedera/TransactionId.h"
|
||||
|
||||
#include "../../tasks/HederaTask.h"
|
||||
|
||||
#include <google/protobuf/util/json_util.h>
|
||||
|
||||
@ -65,21 +57,11 @@ namespace model {
|
||||
return nullptr;
|
||||
}
|
||||
auto group_model = group->getModel();
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
auto topic_id = controller::HederaId::find(group_model->getID(), network_type);
|
||||
|
||||
if (topic_id.isNull()) {
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", group_model->getID()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto body = TransactionBody::create("", user, proto::gradido::GroupMemberUpdate_MemberUpdateType_ADD_USER, group_model->getAlias());
|
||||
|
||||
Poco::AutoPtr<Transaction> result = new Transaction(body);
|
||||
auto model = result->getModel();
|
||||
model->setHederaId(topic_id->getModel()->getID());
|
||||
result->insertPendingTaskIntoDB(user, model::table::TASK_TYPE_GROUP_ADD_MEMBER);
|
||||
PendingTasksManager::getInstance()->addTask(result);
|
||||
return result;
|
||||
@ -99,7 +81,6 @@ namespace model {
|
||||
if (receiver.isNull() || !receiver->getModel()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
auto receiver_model = receiver->getModel();
|
||||
|
||||
auto body = TransactionBody::create(memo, receiver, amount, targetDate, blockchainType);
|
||||
@ -107,17 +88,7 @@ namespace model {
|
||||
|
||||
result->setParam("blockchain_type", (int)blockchainType);
|
||||
auto model = result->getModel();
|
||||
if (blockchainType == BLOCKCHAIN_HEDERA) {
|
||||
auto topic_id = controller::HederaId::find(receiver_model->getGroupId(), network_type);
|
||||
|
||||
if (topic_id.isNull()) {
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", receiver_model->getGroupId()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return nullptr;
|
||||
}
|
||||
model->setHederaId(topic_id->getModel()->getID());
|
||||
}
|
||||
|
||||
result->insertPendingTaskIntoDB(receiver, model::table::TASK_TYPE_CREATION);
|
||||
PendingTasksManager::getInstance()->addTask(result);
|
||||
@ -136,7 +107,6 @@ namespace model {
|
||||
{
|
||||
Poco::AutoPtr<Transaction> transaction;
|
||||
Poco::AutoPtr<TransactionBody> transaction_body;
|
||||
Poco::AutoPtr<controller::HederaId> topic_id;
|
||||
auto em = ErrorManager::getInstance();
|
||||
static const char* function_name = "Transaction::create transfer";
|
||||
|
||||
@ -151,75 +121,6 @@ namespace model {
|
||||
transaction_body = TransactionBody::create(memo, sender, receiverPubkey, amount, blockchainType);
|
||||
transaction = new Transaction(transaction_body);
|
||||
}
|
||||
else if (blockchainType == BLOCKCHAIN_HEDERA)
|
||||
{
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
|
||||
|
||||
// LOCAL Transfer
|
||||
if (receiverGroup.isNull() || sender_model->getGroupId() == receiverGroup->getModel()->getID())
|
||||
{
|
||||
topic_id = controller::HederaId::find(sender_model->getGroupId(), network_type);
|
||||
|
||||
if (topic_id.isNull())
|
||||
{
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", sender_model->getGroupId()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
transaction_body = TransactionBody::create(memo, sender, receiverPubkey, amount, blockchainType);
|
||||
transaction = new Transaction(transaction_body);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto sender_group = controller::Group::load(sender_model->getGroupId());
|
||||
if (sender_group.isNull())
|
||||
{
|
||||
em->addError(new ParamError(function_name, "couldn't find group with id: ", sender_model->getGroupId()));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
Poco::AutoPtr<controller::Group> transaction_group;
|
||||
Poco::AutoPtr<controller::Group> topic_group;
|
||||
// default constructor set it to now
|
||||
Poco::Timestamp pairedTransactionId;
|
||||
// create only inbound transaction, and outbound before sending to hedera
|
||||
//for (int i = 0; i < 1; i++) {
|
||||
if (!inbound) {
|
||||
transaction_group = receiverGroup;
|
||||
topic_group = sender_group;
|
||||
}
|
||||
// transaction send to receiver blockchain
|
||||
else if (inbound) {
|
||||
transaction_group = sender_group;
|
||||
topic_group = receiverGroup;
|
||||
}
|
||||
auto topic_id = controller::HederaId::find(topic_group->getModel()->getID(), network_type);
|
||||
if (topic_id.isNull()) {
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", sender_model->getGroupId()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
if (transaction_group.isNull()) {
|
||||
em->addError(new ParamError(function_name, "transaction group is zero, inbound", inbound));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
|
||||
auto body = TransactionBody::create(memo, sender, receiverPubkey, amount, blockchainType, pairedTransactionId, transaction_group);
|
||||
Poco::AutoPtr<Transaction> transaction = new Transaction(body);
|
||||
|
||||
auto transfer_transaction = transaction->getTransactionBody()->getTransferTransaction();
|
||||
transfer_transaction->setOwnGroupAlias(sender_group->getModel()->getAlias());
|
||||
transfer_transaction->setTargetGroupAlias(receiverGroup->getModel()->getAlias());
|
||||
|
||||
}
|
||||
auto transaction_model = transaction->getModel();
|
||||
transaction_model->setHederaId(topic_id->getModel()->getID());
|
||||
|
||||
}
|
||||
|
||||
transaction->setParam("blockchain_type", (int)blockchainType);
|
||||
transaction->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER);
|
||||
@ -228,25 +129,6 @@ namespace model {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
bool Transaction::setTopicIdByGroup(const std::string& alias)
|
||||
{
|
||||
static const char* function_name = "Transaction::setTopicIdByGroup";
|
||||
auto topic_groups = controller::Group::load(alias);
|
||||
if (topic_groups.size() != 1) {
|
||||
addError(new ParamError(function_name, "not one group found for alias: ", alias));
|
||||
sendErrorsAsEmail();
|
||||
return false;
|
||||
}
|
||||
auto topic = controller::HederaId::find(topic_groups[0]->getModel()->getID(), ServerConfig::g_HederaNetworkType);
|
||||
if (topic.isNull()) {
|
||||
addError(new ParamError(function_name, "no topic found for group id", topic_groups[0]->getModel()->getID()));
|
||||
addError(new ParamError(function_name, "and network type: ", ServerConfig::g_HederaNetworkType));
|
||||
sendErrorsAsEmail();
|
||||
return false;
|
||||
}
|
||||
getModel()->setHederaId(topic->getModel()->getID());
|
||||
return true;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<Transaction> Transaction::createTransfer(
|
||||
const MemoryBin* senderPubkey,
|
||||
@ -267,7 +149,6 @@ namespace model {
|
||||
|
||||
//std::vector<Poco::AutoPtr<TransactionBody>> bodys;
|
||||
auto receiver_model = receiver->getModel();
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
|
||||
auto sender_groups = controller::Group::load(senderGroupAlias);
|
||||
if (!sender_groups.size()) {
|
||||
@ -298,16 +179,7 @@ namespace model {
|
||||
|
||||
auto body = TransactionBody::create(memo, senderPubkey, receiver, amount, pairedTransactionId, transaction_group);
|
||||
result = new Transaction(body);
|
||||
if (blockchainType == BLOCKCHAIN_HEDERA) {
|
||||
auto topic_id = controller::HederaId::find(topic_group->getModel()->getID(), network_type);
|
||||
if (topic_id.isNull()) {
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", receiver_model->getGroupId()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return result;
|
||||
}
|
||||
result->getModel()->setHederaId(topic_id->getModel()->getID());
|
||||
}
|
||||
|
||||
result->setParam("blockchain_type", (int)blockchainType);
|
||||
result->insertPendingTaskIntoDB(receiver, model::table::TASK_TYPE_TRANSFER);
|
||||
PendingTasksManager::getInstance()->addTask(result);
|
||||
@ -484,9 +356,10 @@ namespace model {
|
||||
|
||||
}
|
||||
}
|
||||
UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr<Transaction>(this, true)));
|
||||
transaction_send_task->scheduleTask(transaction_send_task);
|
||||
return true;
|
||||
//UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr<Transaction>(this, true)));
|
||||
//transaction_send_task->scheduleTask(transaction_send_task);
|
||||
return 1 == runSendTransaction();
|
||||
//return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -637,15 +510,14 @@ namespace model {
|
||||
|
||||
auto pt = PendingTasksManager::getInstance();
|
||||
pt->reportErrorToCommunityServer(Poco::AutoPtr<Transaction>(this, true), error_name, error_description);
|
||||
addError(new ParamError(function_name, error_name, error_description));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mTransactionBody->isHederaBlockchain()) {
|
||||
return runSendTransactionHedera();
|
||||
}
|
||||
else if (mTransactionBody->isMysqlBlockchain()) {
|
||||
|
||||
if (mTransactionBody->isMysqlBlockchain()) {
|
||||
return runSendTransactionMysql();
|
||||
}
|
||||
addError(new ParamError(function_name, "not implemented blockchain type", mTransactionBody->getBlockchainTypeString()));
|
||||
@ -654,145 +526,6 @@ namespace model {
|
||||
|
||||
}
|
||||
|
||||
int Transaction::runSendTransactionHedera()
|
||||
{
|
||||
static const char* function_name = "Transaction::runSendTransactionHedera";
|
||||
// send transaction via hedera
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
// TODO: get correct topic id for user group
|
||||
//int user_group_id = 1;
|
||||
//auto topic_id = controller::HederaId::find(user_group_id, network_type);
|
||||
auto topic_id = controller::HederaId::load(getModel()->getHederaId());
|
||||
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);
|
||||
std::string raw_message = mProtoTransaction.SerializeAsString();
|
||||
|
||||
if (ServerConfig::HEDERA_CONSENSUS_FORMAT_BINARY == ServerConfig::g_ConsensusMessageFormat) {
|
||||
consensus_submit_message.setMessage(raw_message);
|
||||
|
||||
// print to txt for debugging gradido node
|
||||
static Poco::FastMutex _file_mutex;
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock_file(_file_mutex);
|
||||
std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S") + "\n";
|
||||
|
||||
std::string json_message = getTransactionAsJson();
|
||||
std::string base64_message = DataTypeConverter::binToBase64((const unsigned char*)raw_message.data(), raw_message.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
||||
if (json_message != "")
|
||||
{
|
||||
Poco::Logger& transactions_log = Poco::Logger::get("transactions_log");
|
||||
transactions_log.information(dateTimeString);
|
||||
transactions_log.information(json_message);
|
||||
}
|
||||
if (base64_message != "")
|
||||
{
|
||||
Poco::Logger& transaction_log_base64 = Poco::Logger::get("transactions_log_base64");
|
||||
transaction_log_base64.information(dateTimeString);
|
||||
transaction_log_base64.information(base64_message);
|
||||
}
|
||||
}
|
||||
else if (ServerConfig::HEDERA_CONSENSUS_FORMAT_BASE64_URLSAVE_NO_PADDING == ServerConfig::g_ConsensusMessageFormat) {
|
||||
consensus_submit_message.setMessage(DataTypeConverter::binToBase64((const unsigned char*)raw_message.data(), raw_message.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING));
|
||||
}
|
||||
else if (ServerConfig::HEDERA_CONSENSUS_FORMAT_JSON == ServerConfig::g_ConsensusMessageFormat) {
|
||||
std::string json_message = getTransactionAsJson();
|
||||
if (json_message != "") {
|
||||
consensus_submit_message.setMessage(json_message);
|
||||
}
|
||||
else {
|
||||
//sendErrorsAsEmail();
|
||||
return -7;
|
||||
}
|
||||
|
||||
}
|
||||
// if using testnet, transfer message base64 encoded to check messages in hedera block explorer
|
||||
//if (network_type == table::HEDERA_TESTNET) {
|
||||
//consensus_submit_message.setMessage(DataTypeConverter::binToBase64((const unsigned char*)raw_message.data(), raw_message.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING));
|
||||
//}
|
||||
//else {
|
||||
|
||||
//}
|
||||
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;
|
||||
Poco::AutoPtr<HederaTask> hedera_task(new HederaTask(this));
|
||||
|
||||
if (HEDERA_REQUEST_RETURN_OK != hedera_request.request(&hedera_transaction, hedera_task))
|
||||
{
|
||||
addError(new Error(function_name, "error send transaction to hedera"));
|
||||
getErrors(&hedera_request);
|
||||
//sendErrorsAsEmail();
|
||||
return -2;
|
||||
}
|
||||
else {
|
||||
auto hedera_transaction_response = hedera_task->getTransactionResponse();
|
||||
auto hedera_precheck_code_string = hedera_transaction_response->getPrecheckCodeString();
|
||||
auto precheck_code = hedera_transaction_response->getPrecheckCode();
|
||||
auto cost = hedera_transaction_response->getCost();
|
||||
|
||||
// for showing in docker
|
||||
std::clog << "hedera response: " << hedera_precheck_code_string
|
||||
<< ", cost: " << cost
|
||||
<< ", type: " << TransactionBody::transactionTypeToString(mTransactionBody->getType())
|
||||
<< std::endl;
|
||||
/*printf("hedera response: %s, cost: %" PRIu64 ", type: %s\n",
|
||||
hedera_precheck_code_string.data(), cost,
|
||||
TransactionBody::transactionTypeToString(mTransactionBody->getType()));*/
|
||||
if (precheck_code == proto::INVALID_TRANSACTION_START) {
|
||||
int zahl = 0;
|
||||
return -5;
|
||||
}
|
||||
else if (precheck_code == proto::OK) {
|
||||
// simply assume if transaction was sended to hedera without error, it was also accepted from gradido node
|
||||
// TODO: later check, but now I haven't any way to communicate with the gradido node
|
||||
mTransactionBody->getTransactionBase()->transactionAccepted(getUser());
|
||||
auto transaction_model = getModel();
|
||||
transaction_model->setFinished(Poco::DateTime());
|
||||
Poco::JSON::Object::Ptr result = new Poco::JSON::Object;
|
||||
model::hedera::TransactionId transaction_id(hedera_task->getTransactionId());
|
||||
result->set("state", "success");
|
||||
result->set("transactionId", transaction_id.convertToJSON());
|
||||
|
||||
transaction_model->setResultJson(result);
|
||||
Profiler timer;
|
||||
transaction_model->updateFinishedAndResult();
|
||||
printf("time for update 2 fields in db: %s\n", timer.string().data());
|
||||
|
||||
// trigger community server update in 5 seconds
|
||||
CronManager::getInstance()->scheduleUpdateRun(Poco::Timespan(5, 0));
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
//model::hedera::TransactionBody hedera_transaction_body()
|
||||
}
|
||||
else
|
||||
{
|
||||
addError(new ParamError(function_name, "hedera crypto key not found for paying for consensus submit message! NetworkType: ", network_type));
|
||||
//sendErrorsAsEmail();
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addError(new Error(function_name, "hedera topic id or operator account not found!"));
|
||||
addError(new ParamError(function_name, "topic id: ", topic_id->getModel()->toString()));
|
||||
addError(new ParamError(function_name, "network type: ", network_type));
|
||||
//sendErrorsAsEmail();
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
int Transaction::runSendTransactionMysql()
|
||||
{
|
||||
static const char* function_name = "Transaction::runSendTransactionMysql";
|
||||
@ -832,6 +565,10 @@ namespace model {
|
||||
if (!json_request.errorCount()) {
|
||||
finishSuccess();
|
||||
}
|
||||
else {
|
||||
getErrors(&json_request);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -86,14 +86,11 @@ namespace model {
|
||||
std::string getTransactionAsJson(bool replaceBase64WithHex = false);
|
||||
inline Poco::AutoPtr<Transaction> getPairedTransaction() { return mPairedTransaction; }
|
||||
|
||||
bool setTopicIdByGroup(const std::string& alias);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool ifEnoughSignsProceed(Poco::AutoPtr<controller::User> user);
|
||||
|
||||
int runSendTransactionHedera();
|
||||
int runSendTransactionMysql();
|
||||
|
||||
Poco::AutoPtr<Transaction> mPairedTransaction;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#include "TransactionTransfer.h"
|
||||
#include "Transaction.h"
|
||||
#include "../../SingletonManager/ErrorManager.h"
|
||||
#include "../../controller/HederaId.h"
|
||||
|
||||
namespace model {
|
||||
namespace gradido {
|
||||
@ -68,7 +67,7 @@ namespace model {
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
const static char functionName[] = { "TransactionTransfer::prepare" };
|
||||
|
||||
mKontoTable.reserve(2);
|
||||
mKontoTable.reserve(2);
|
||||
|
||||
proto::gradido::TransferAmount* sender = nullptr;
|
||||
std::string* receiver_pubkey = nullptr;
|
||||
@ -83,7 +82,7 @@ namespace model {
|
||||
sender = inbound_transfer.mutable_sender();
|
||||
receiver_pubkey = inbound_transfer.mutable_receiver();
|
||||
return prepare(sender, receiver_pubkey);
|
||||
}
|
||||
}
|
||||
else if (mProtoTransfer.has_outbound()) {
|
||||
auto outbound_transfer = mProtoTransfer.outbound();
|
||||
sender = outbound_transfer.mutable_sender();
|
||||
@ -156,7 +155,7 @@ namespace model {
|
||||
receiver_pubkey = outbound_transfer.mutable_receiver();
|
||||
return validate(sender, receiver_pubkey);
|
||||
}
|
||||
|
||||
|
||||
return TRANSACTION_VALID_CODE_ERROR;
|
||||
}
|
||||
|
||||
@ -234,12 +233,11 @@ namespace model {
|
||||
);
|
||||
|
||||
auto transaction = Poco::AutoPtr<Transaction>(new Transaction(body));
|
||||
transaction->setTopicIdByGroup(mOwnGroupAlias);
|
||||
|
||||
mm->releaseMemory(receiver_pubkey);
|
||||
mm->releaseMemory(sender_pubkey);
|
||||
return transaction;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<Transaction> TransactionTransfer::createInbound(const std::string& memo)
|
||||
@ -253,12 +251,12 @@ namespace model {
|
||||
// Poco::AutoPtr<controller::User> sender, const MemoryBin* receiverPubkey, Poco::AutoPtr<controller::Group> receiverGroup, Poco::UInt32 amount, const std::string& memo
|
||||
//Transaction::createTransfer()
|
||||
auto outbound = mProtoTransfer.outbound();
|
||||
|
||||
|
||||
auto sender_pubkey = mm->getFreeMemory(outbound.sender().pubkey().size());
|
||||
memcpy(*sender_pubkey, outbound.sender().pubkey().data(), outbound.sender().pubkey().size());
|
||||
auto receiver_pubkey = mm->getFreeMemory(outbound.receiver().size());
|
||||
memcpy(*receiver_pubkey, outbound.receiver().data(), outbound.receiver().size());
|
||||
|
||||
|
||||
auto body = TransactionBody::create(
|
||||
memo, sender_pubkey, receiver_pubkey,
|
||||
outbound.sender().amount(), mOwnGroupAlias, TRANSFER_CROSS_GROUP_INBOUND,
|
||||
@ -266,8 +264,7 @@ namespace model {
|
||||
);
|
||||
|
||||
auto transaction = Poco::AutoPtr<Transaction>(new Transaction(body));
|
||||
transaction->setTopicIdByGroup(mTargetGroupAlias);
|
||||
|
||||
|
||||
mm->releaseMemory(receiver_pubkey);
|
||||
mm->releaseMemory(sender_pubkey);
|
||||
return transaction;
|
||||
@ -276,7 +273,7 @@ namespace model {
|
||||
const std::string& TransactionTransfer::getKontoNameCell(int index)
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
|
||||
if (index >= mKontoTable.size()) {
|
||||
return mInvalidIndexMessage;
|
||||
}
|
||||
@ -299,7 +296,7 @@ namespace model {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
|
||||
|
||||
#include "ConsensusCreateTopic.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
ConsensusCreateTopic::ConsensusCreateTopic(Poco::AutoPtr<controller::HederaId> autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod)
|
||||
: mProtoCreateTopic(nullptr)
|
||||
{
|
||||
mProtoCreateTopic = new proto::ConsensusCreateTopicTransactionBody;
|
||||
auto auto_renew_period = mProtoCreateTopic->mutable_autorenewperiod();
|
||||
auto_renew_period->set_seconds(autoRenewPeriod);
|
||||
|
||||
if (!autoRenewHederaAccountId.isNull()) {
|
||||
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() == 7890000) {// && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
|
||||
|
||||
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
#include "../../controller/HederaId.h"
|
||||
#include "proto/hedera/ConsensusCreateTopic.pb.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class ConsensusCreateTopic
|
||||
{
|
||||
public:
|
||||
ConsensusCreateTopic(Poco::AutoPtr<controller::HederaId> 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
|
||||
@ -1,42 +0,0 @@
|
||||
#include "ConsensusSubmitMessage.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
ConsensusSubmitMessage::ConsensusSubmitMessage(Poco::AutoPtr<controller::HederaId> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#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<controller::HederaId> 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
|
||||
@ -1,68 +0,0 @@
|
||||
#include "ConsensusTopicInfo.h"
|
||||
|
||||
#include <sstream>
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
ConsensusTopicInfo::ConsensusTopicInfo(const proto::ConsensusTopicInfo& consensusTopicInfo)
|
||||
: mProto(consensusTopicInfo)
|
||||
{
|
||||
}
|
||||
|
||||
ConsensusTopicInfo::~ConsensusTopicInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemoryBin* ConsensusTopicInfo::getRunningHashCopy() const
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto running_hash = mProto.runninghash();
|
||||
auto running_hash_bin = mm->getFreeMemory(running_hash.size());
|
||||
memcpy(*running_hash_bin, running_hash.data(), running_hash.size());
|
||||
return running_hash_bin;
|
||||
}
|
||||
|
||||
std::string ConsensusTopicInfo::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "memo: " << mProto.memo() << std::endl;
|
||||
ss << "running hash: " << DataTypeConverter::binToHex((const unsigned char*)mProto.runninghash().data(), mProto.runninghash().size()) << std::endl;
|
||||
ss << "sequence number: " << mProto.sequencenumber() << std::endl;
|
||||
Poco::DateTime expiration_time = DataTypeConverter::convertFromProtoTimestamp(mProto.expirationtime());
|
||||
|
||||
ss << "expiration time: " << Poco::DateTimeFormatter::format(expiration_time, "%f.%m.%Y %H:%M:%S") << std::endl;
|
||||
ss << "has admin key: " << mProto.has_adminkey() << std::endl;
|
||||
ss << "has submit key: " << mProto.has_submitkey() << std::endl;
|
||||
auto auto_renew_period = DataTypeConverter::convertFromProtoDuration(mProto.autorenewperiod());
|
||||
ss << "auto renew period: " << std::to_string(auto_renew_period.seconds()) << " seconds" << std::endl;
|
||||
auto acc_id = mProto.autorenewaccount();
|
||||
ss << "auto renew account: " << acc_id.shardnum() << ", " << acc_id.realmnum() << ", " << acc_id.accountnum() << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ConsensusTopicInfo::toStringHtml()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "<ul>";
|
||||
ss << "<li>memo: " << mProto.memo() << "</li>";
|
||||
ss << "<li>running hash: " << DataTypeConverter::binToHex((const unsigned char*)mProto.runninghash().data(), mProto.runninghash().size()) << "</li>";
|
||||
ss << "<li>sequence number: " << mProto.sequencenumber() << "</li>";
|
||||
Poco::DateTime expiration_time = DataTypeConverter::convertFromProtoTimestamp(mProto.expirationtime());
|
||||
|
||||
ss << "<li>expiration time: " << Poco::DateTimeFormatter::format(expiration_time, "%f.%m.%Y %H:%M:%S") << "</li>";
|
||||
ss << "<li>has admin key: " << mProto.has_adminkey() << "</li>";
|
||||
ss << "<li>has submit key: " << mProto.has_submitkey() << "</li>";
|
||||
auto auto_renew_period = DataTypeConverter::convertFromProtoDuration(mProto.autorenewperiod());
|
||||
ss << "<li>auto renew period: " << std::to_string(mProto.autorenewperiod().seconds()) << " seconds" << "</li>";
|
||||
auto acc_id = mProto.autorenewaccount();
|
||||
ss << "<li>auto renew account: " << acc_id.shardnum() << ", " << acc_id.realmnum() << ", " << acc_id.accountnum() << "</li>";
|
||||
ss << "</ul>";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
#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/ConsensusTopicInfo.pb.h"
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
#include "Poco/DateTime.h"
|
||||
|
||||
namespace model
|
||||
{
|
||||
namespace hedera
|
||||
{
|
||||
class ConsensusTopicInfo
|
||||
{
|
||||
public:
|
||||
ConsensusTopicInfo(const proto::ConsensusTopicInfo& consensusTopicInfo);
|
||||
~ConsensusTopicInfo();
|
||||
|
||||
inline std::string getMemo() const { return mProto.memo(); }
|
||||
MemoryBin* getRunningHashCopy() const;
|
||||
Poco::UInt64 getSequenceNumber() const { return mProto.sequencenumber(); }
|
||||
inline Poco::DateTime getExpirationTime() const { return DataTypeConverter::convertFromProtoTimestamp(mProto.expirationtime());}
|
||||
inline proto::Duration getAutoRenewPeriod() const { return mProto.autorenewperiod(); }
|
||||
|
||||
std::string toString();
|
||||
std::string toStringHtml();
|
||||
|
||||
protected:
|
||||
proto::ConsensusTopicInfo mProto;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H
|
||||
@ -1,34 +0,0 @@
|
||||
#include "CryptoCreateTransaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
|
||||
#define __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
|
||||
|
||||
#include "proto/hedera/CryptoCreate.pb.h"
|
||||
|
||||
#include "../../Crypto/KeyPairHedera.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
class CryptoCreateTransaction
|
||||
{
|
||||
public:
|
||||
//! \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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
|
||||
@ -1,48 +0,0 @@
|
||||
#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<controller::HederaId> 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<controller::HederaId> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
#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<controller::HederaId> senderAccountId, Poco::UInt64 amountTinybars);
|
||||
void addReceiver(Poco::AutoPtr<controller::HederaId> receiverAccountId, Poco::UInt64 amountTinybars);
|
||||
|
||||
bool validate();
|
||||
// set pointer to zero, after hand over pointer to transaction body
|
||||
inline void resetPointer() { mCryptoTransfer = nullptr; }
|
||||
|
||||
inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; }
|
||||
|
||||
protected:
|
||||
proto::CryptoTransferTransactionBody* mCryptoTransfer;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H
|
||||
@ -1,193 +0,0 @@
|
||||
#include "Query.h"
|
||||
#include "QueryHeader.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
|
||||
#include <google/protobuf/util/json_util.h>
|
||||
|
||||
#include "Transaction.h"
|
||||
#include "TransactionBody.h"
|
||||
#include "CryptoTransferTransaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
Query::Query()
|
||||
: mTransactionBody(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Query::~Query()
|
||||
{
|
||||
if (mTransactionBody) {
|
||||
delete mTransactionBody;
|
||||
}
|
||||
}
|
||||
|
||||
Query* Query::getBalance(Poco::AutoPtr<controller::HederaId> accountId, const controller::NodeServerConnection& connection)
|
||||
{
|
||||
|
||||
assert(!accountId.isNull() && accountId->getModel());
|
||||
|
||||
printf("[Query::getBalance] account id: %s\n", accountId->getModel()->toString().data());
|
||||
|
||||
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();
|
||||
query_header->set_responsetype(proto::COST_ANSWER);
|
||||
|
||||
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
|
||||
// node account id
|
||||
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
Query* Query::getTopicInfo(Poco::AutoPtr<controller::HederaId> topicId, Poco::AutoPtr<controller::HederaId> payerAccountId, const controller::NodeServerConnection& connection)
|
||||
{
|
||||
assert(!topicId.isNull() && topicId->getModel());
|
||||
assert(!payerAccountId.isNull() && payerAccountId->getModel());
|
||||
|
||||
printf("[Query::getTopicInfo] topic id: %s\n", topicId->getModel()->toString().data());
|
||||
printf("[Query::getTopicInfo] payer account id: %s\n", payerAccountId->getModel()->toString().data());
|
||||
|
||||
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.003317 Hashbars
|
||||
// fee from https://www.hedera.com/fees
|
||||
crypto_transaction.addSender(payerAccountId, 3317);
|
||||
crypto_transaction.addReceiver(connection.hederaId, 3317);
|
||||
query->mTransactionBody->setCryptoTransfer(crypto_transaction);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
Query* Query::getTransactionGetReceiptQuery(
|
||||
const proto::TransactionID& transactionId,
|
||||
Poco::AutoPtr<controller::HederaAccount> payerAccount,
|
||||
const controller::NodeServerConnection& connection
|
||||
)
|
||||
{
|
||||
assert(!payerAccount.isNull());
|
||||
auto query = new Query;
|
||||
query->mQueryHeader = QueryHeader::createWithPaymentTransaction(payerAccount, connection, 1000);
|
||||
auto transaction_get_receipt_query = query->mQueryProto.mutable_transactiongetreceipt();
|
||||
transaction_get_receipt_query->set_allocated_header(query->mQueryHeader->getProtoQueryHeader());
|
||||
auto transaction_id = transaction_get_receipt_query->mutable_transactionid();
|
||||
*transaction_id = transactionId;
|
||||
|
||||
return query;
|
||||
}
|
||||
Query* Query::getTransactionGetRecordQuery(
|
||||
const proto::TransactionID& transactionId,
|
||||
Poco::AutoPtr<controller::HederaAccount> payerAccount,
|
||||
const controller::NodeServerConnection& connection
|
||||
)
|
||||
{
|
||||
assert(!payerAccount.isNull());
|
||||
auto query = new Query;
|
||||
query->mQueryHeader = QueryHeader::createWithPaymentTransaction(payerAccount, connection, 1000);
|
||||
|
||||
auto transaction_get_record_query = query->mQueryProto.mutable_transactiongetrecord();
|
||||
transaction_get_record_query->set_allocated_header(query->mQueryHeader->getProtoQueryHeader());
|
||||
auto transaction_id = transaction_get_record_query->mutable_transactionid();
|
||||
*transaction_id = transactionId;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
std::string Query::getConnectionString() const
|
||||
{
|
||||
if (mTransactionBody) {
|
||||
return mTransactionBody->getConnectionString();
|
||||
}
|
||||
if (!mQueryHeader.isNull()) {
|
||||
return mQueryHeader->getConnectionString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
proto::QueryHeader* Query::getQueryHeader()
|
||||
{
|
||||
if (mQueryProto.has_cryptogetaccountbalance()) {
|
||||
return mQueryProto.mutable_cryptogetaccountbalance()->mutable_header();
|
||||
}
|
||||
else if (mQueryProto.has_consensusgettopicinfo()) {
|
||||
return mQueryProto.mutable_consensusgettopicinfo()->mutable_header();
|
||||
}
|
||||
else {
|
||||
return mQueryHeader->getProtoQueryHeader();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Query::sign(std::unique_ptr<KeyPairHedera> keyPairHedera)
|
||||
{
|
||||
Transaction transaction;
|
||||
mTransactionBody->updateTimestamp();
|
||||
auto sign_result = transaction.sign(std::move(keyPairHedera), mTransactionBody);
|
||||
auto query_header = getQueryHeader();
|
||||
query_header->set_allocated_payment(transaction.getTransaction());
|
||||
transaction.resetPointer();
|
||||
|
||||
return sign_result;
|
||||
}
|
||||
|
||||
void Query::setResponseType(proto::ResponseType type)
|
||||
{
|
||||
auto query_header = getQueryHeader();
|
||||
query_header->set_responsetype(type);
|
||||
}
|
||||
|
||||
proto::ResponseType Query::getResponseType()
|
||||
{
|
||||
auto query_header = getQueryHeader();
|
||||
return query_header->responsetype();
|
||||
}
|
||||
|
||||
std::string Query::toJsonString() const
|
||||
{
|
||||
std::string json_message = "";
|
||||
std::string json_message_body = "";
|
||||
google::protobuf::util::JsonPrintOptions options;
|
||||
options.add_whitespace = true;
|
||||
options.always_print_primitive_fields = true;
|
||||
|
||||
auto status = google::protobuf::util::MessageToJsonString(mQueryProto, &json_message, options);
|
||||
if (!status.ok()) {
|
||||
return "error parsing query";
|
||||
}
|
||||
|
||||
if (mTransactionBody) {
|
||||
status = google::protobuf::util::MessageToJsonString(*mTransactionBody->getProtoTransactionBody(), &json_message_body, options);
|
||||
if (!status.ok()) {
|
||||
return "error parsing body";
|
||||
}
|
||||
//\"bodyBytes\": \"MigKIC7Sihz14RbYNhVAa8V3FSIhwvd0pWVvZqDnVA91dtcbIgRnZGQx\"
|
||||
int startBodyBytes = json_message.find("bodyBytes") + std::string("\"bodyBytes\": \"").size() - 2;
|
||||
int endCur = json_message.find_first_of('\"', startBodyBytes + 2) + 1;
|
||||
json_message.replace(startBodyBytes, endCur - startBodyBytes, json_message_body);
|
||||
}
|
||||
return json_message;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
#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"
|
||||
#include "TransactionBody.h"
|
||||
#include "QueryHeader.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class Query
|
||||
{
|
||||
public:
|
||||
~Query();
|
||||
static Query* getBalance(Poco::AutoPtr<controller::HederaId> accountId, const controller::NodeServerConnection& connection);
|
||||
static Query* getTopicInfo(Poco::AutoPtr<controller::HederaId> topicId, Poco::AutoPtr<controller::HederaId> payerAccountId, const controller::NodeServerConnection& connection);
|
||||
static Query* getTransactionGetReceiptQuery(
|
||||
const proto::TransactionID& transactionId,
|
||||
Poco::AutoPtr<controller::HederaAccount> payerAccount,
|
||||
const controller::NodeServerConnection& connection
|
||||
);
|
||||
static Query* getTransactionGetRecordQuery(
|
||||
const proto::TransactionID& transactionId,
|
||||
Poco::AutoPtr<controller::HederaAccount> payerAccount,
|
||||
const controller::NodeServerConnection& connection
|
||||
);
|
||||
bool sign(std::unique_ptr<KeyPairHedera> 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; }
|
||||
std::string getConnectionString() const;
|
||||
|
||||
proto::QueryHeader* getQueryHeader();
|
||||
|
||||
std::string toJsonString() const;
|
||||
|
||||
protected:
|
||||
Query();
|
||||
proto::Query mQueryProto;
|
||||
Poco::AutoPtr<QueryHeader> mQueryHeader;
|
||||
TransactionBody* mTransactionBody;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H
|
||||
@ -1,43 +0,0 @@
|
||||
#include "QueryHeader.h"
|
||||
|
||||
#include "Transaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
QueryHeader::QueryHeader()
|
||||
{
|
||||
mProtoQueryHeader.set_responsetype(proto::ANSWER_ONLY);
|
||||
}
|
||||
|
||||
QueryHeader::~QueryHeader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<QueryHeader> QueryHeader::createWithPaymentTransaction(
|
||||
Poco::AutoPtr<controller::HederaAccount> operatorAccount,
|
||||
const controller::NodeServerConnection& connection,
|
||||
Poco::UInt32 cost
|
||||
) {
|
||||
Poco::AutoPtr<QueryHeader> query_header(new QueryHeader);
|
||||
auto proto_query_header = query_header->getProtoQueryHeader();
|
||||
proto_query_header->set_responsetype(proto::ANSWER_ONLY);
|
||||
auto payment_transaction = proto_query_header->mutable_payment();
|
||||
|
||||
query_header->mConnectionString = connection.getUriWithPort();
|
||||
|
||||
Transaction transactionObj(payment_transaction);
|
||||
TransactionBody body(operatorAccount->getHederaId(), connection);
|
||||
CryptoTransferTransaction transfer_transaction;
|
||||
transfer_transaction.addSender(operatorAccount->getHederaId(), cost);
|
||||
transfer_transaction.addReceiver(connection.hederaId, cost);
|
||||
body.setCryptoTransfer(transfer_transaction);
|
||||
transactionObj.sign(operatorAccount->getCryptoKey()->getKeyPair(), &body);
|
||||
transactionObj.resetPointer();
|
||||
|
||||
return query_header;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
#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"
|
||||
|
||||
#include "../../controller/User.h"
|
||||
#include "../../controller/HederaAccount.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class QueryHeader : public Poco::RefCountedObject
|
||||
{
|
||||
public:
|
||||
~QueryHeader();
|
||||
|
||||
//! for cost look here: https://www.hedera.com/fees
|
||||
//! or make query first with response type COST_ANSWER
|
||||
//! TODO: get cost from network
|
||||
static Poco::AutoPtr<QueryHeader> createWithPaymentTransaction(
|
||||
Poco::AutoPtr<controller::HederaAccount> operatorAccount,
|
||||
const controller::NodeServerConnection& connection,
|
||||
Poco::UInt32 cost
|
||||
);
|
||||
|
||||
void setResponseType(proto::ResponseType type) { mProtoQueryHeader.set_responsetype(type); };
|
||||
proto::ResponseType getResponseType() const { return mProtoQueryHeader.responsetype(); }
|
||||
|
||||
proto::QueryHeader* getProtoQueryHeader() { return &mProtoQueryHeader; }
|
||||
|
||||
const std::string& getConnectionString() const { return mConnectionString; }
|
||||
|
||||
protected:
|
||||
proto::QueryHeader mProtoQueryHeader;
|
||||
std::string mConnectionString;
|
||||
QueryHeader();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H
|
||||
@ -1,78 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
std::unique_ptr<ConsensusTopicInfo> Response::getConsensusTopicInfo()
|
||||
{
|
||||
if (mResponseProto.has_consensusgettopicinfo()) {
|
||||
return std::make_unique<ConsensusTopicInfo>(mResponseProto.consensusgettopicinfo().topicinfo());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TransactionReceipt* Response::getTransactionReceipt()
|
||||
{
|
||||
if (mResponseProto.has_transactiongetreceipt()) {
|
||||
return new TransactionReceipt(mResponseProto.transactiongetreceipt().receipt());
|
||||
}
|
||||
if (mResponseProto.has_transactiongetrecord()) {
|
||||
return new TransactionReceipt(mResponseProto.transactiongetrecord().transactionrecord().receipt());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TransactionRecord* Response::getTransactionRecord()
|
||||
{
|
||||
if (mResponseProto.has_transactiongetrecord()) {
|
||||
return new TransactionRecord(mResponseProto.transactiongetrecord().transactionrecord());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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()) {
|
||||
auto balance_response = mResponseProto.cryptogetaccountbalance();
|
||||
return balance_response.header().nodetransactionprecheckcode();
|
||||
}
|
||||
else if (mResponseProto.has_consensusgettopicinfo()) {
|
||||
auto response = mResponseProto.consensusgettopicinfo();
|
||||
return response.header().nodetransactionprecheckcode();
|
||||
}
|
||||
return proto::NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
#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 "ConsensusTopicInfo.h"
|
||||
#include "TransactionReceipt.h"
|
||||
#include "TransactionRecord.h"
|
||||
#include "Poco/Types.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class Response
|
||||
{
|
||||
public:
|
||||
Response();
|
||||
~Response();
|
||||
|
||||
inline proto::Response* getResponsePtr() { return &mResponseProto; }
|
||||
Poco::UInt64 getAccountBalance();
|
||||
std::unique_ptr<ConsensusTopicInfo> getConsensusTopicInfo();
|
||||
TransactionReceipt* getTransactionReceipt();
|
||||
TransactionRecord* getTransactionRecord();
|
||||
Poco::UInt64 getQueryCost();
|
||||
proto::ResponseCodeEnum getResponseCode();
|
||||
|
||||
|
||||
inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); }
|
||||
inline bool isConsensusGetTopicInfoResponse() { return mResponseProto.has_consensusgettopicinfo(); }
|
||||
|
||||
protected:
|
||||
proto::Response mResponseProto;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H
|
||||
@ -1,81 +0,0 @@
|
||||
#include "Transaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
Transaction::Transaction()
|
||||
: mTransaction(nullptr)
|
||||
{
|
||||
mTransaction = new proto::Transaction;
|
||||
}
|
||||
Transaction::Transaction(proto::Transaction* transaction)
|
||||
: mTransaction(transaction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Transaction::~Transaction()
|
||||
{
|
||||
if (mTransaction) {
|
||||
delete mTransaction;
|
||||
mTransaction = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Transaction::sign(std::unique_ptr<KeyPairHedera> keyPairHedera, const TransactionBody* 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());
|
||||
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;
|
||||
}
|
||||
|
||||
bool Transaction::sign(std::unique_ptr<KeyPairHedera> keyPairHedera, std::unique_ptr<TransactionBody> transactionBody)
|
||||
{
|
||||
mType = transactionBody->getType();
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
mConnection = transactionBody->getConnection();
|
||||
transactionBody->updateTimestamp();
|
||||
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();
|
||||
|
||||
mTransactionId = transactionBody->getProtoTransactionBody()->transactionid();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
#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(proto::Transaction* transaction);
|
||||
~Transaction();
|
||||
|
||||
bool sign(std::unique_ptr<KeyPairHedera> keyPairHedera, const TransactionBody* transactionBody);
|
||||
bool sign(std::unique_ptr<KeyPairHedera> keyPairHedera, std::unique_ptr<TransactionBody> transactionBody);
|
||||
|
||||
inline proto::Transaction* getTransaction() { return mTransaction; }
|
||||
inline std::string getConnectionString() const { return mConnection.getUriWithPort(); }
|
||||
const controller::NodeServerConnection& getConnection() const { return mConnection; }
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H
|
||||
@ -1,153 +0,0 @@
|
||||
#include "TransactionBody.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionBody::TransactionBody(Poco::AutoPtr<controller::HederaId> operatorAccountId, const controller::NodeServerConnection& connection)
|
||||
: mConnection(connection), mHasBody(false)
|
||||
{
|
||||
connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid());
|
||||
auto transaction_id = mTransactionBody.mutable_transactionid();
|
||||
operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid());
|
||||
mTransactionBody.set_transactionfee(10000000);
|
||||
auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration();
|
||||
transaction_valid_duration->set_seconds(120);
|
||||
|
||||
updateTimestamp();
|
||||
}
|
||||
|
||||
TransactionBody::~TransactionBody()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
mTransactionBody.set_transactionfee(1000000000);
|
||||
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;
|
||||
}
|
||||
|
||||
const char* TransactionBody::TransactionBodyTypeToString(TransactionBodyType type)
|
||||
{
|
||||
switch (type) {
|
||||
case TRANSACTION_CONSENSUS_CREATE_TOPIC: return "Consensus Create Topic";
|
||||
case TRANSACTION_CONSENSUS_SUBMIT_MESSAGE: return "Consensus Submit Message";
|
||||
case TRANSACTION_CRYPTO_CREATE: return "Crypto Create";
|
||||
case TRANSACTION_CRYPTO_TRANSFER: return "Crypto Transfer";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
void TransactionBody::setMemo(const std::string& memo)
|
||||
{
|
||||
mTransactionBody.set_memo(memo);
|
||||
}
|
||||
void TransactionBody::setFee(Poco::UInt64 fee)
|
||||
{
|
||||
mTransactionBody.set_transactionfee(fee);
|
||||
}
|
||||
|
||||
void TransactionBody::updateTimestamp()
|
||||
{
|
||||
auto transaction_id = mTransactionBody.mutable_transactionid();
|
||||
auto timestamp = transaction_id->mutable_transactionvalidstart();
|
||||
Poco::Timestamp now;
|
||||
auto micros = now.epochMicroseconds();
|
||||
auto s = now.epochTime();
|
||||
auto res = now.resolution();
|
||||
auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6
|
||||
// 1s = 1000000000 ns
|
||||
timestamp->set_seconds(now.epochTime()-2);
|
||||
timestamp->set_nanos(microseconds * 1000);
|
||||
// make sure timestamp is some nanos old
|
||||
//timestamp->set_nanos(microseconds * 900);
|
||||
// printf("hedera transaction body timestamp: %d.%d\n", timestamp->seconds(), timestamp->nanos());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
#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 "../../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:
|
||||
TransactionBody(Poco::AutoPtr<controller::HederaId> operatorAccountId, const controller::NodeServerConnection& connection);
|
||||
~TransactionBody();
|
||||
|
||||
void setMemo(const std::string& memo);
|
||||
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);
|
||||
//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; }
|
||||
static const char* TransactionBodyTypeToString(TransactionBodyType type);
|
||||
|
||||
void updateTimestamp();
|
||||
protected:
|
||||
|
||||
proto::TransactionBody mTransactionBody;
|
||||
controller::NodeServerConnection mConnection;
|
||||
bool mHasBody;
|
||||
TransactionBodyType mType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H
|
||||
@ -1,15 +0,0 @@
|
||||
#include "TransactionGetReceipt.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionGetReceipt::TransactionGetReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionGetReceipt::~TransactionGetReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_H
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_H
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionGetReceipt
|
||||
{
|
||||
public:
|
||||
TransactionGetReceipt();
|
||||
~TransactionGetReceipt();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_H
|
||||
@ -1,18 +0,0 @@
|
||||
#include "TransactionGetReceiptQuery.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionGetReceiptQuery::TransactionGetReceiptQuery(Poco::AutoPtr<QueryHeader> queryHeader, const Transaction* target)
|
||||
: mQueryHeader(queryHeader)
|
||||
{
|
||||
mProtoReceiptQuery.set_allocated_header(queryHeader->getProtoQueryHeader());
|
||||
auto transaction_id = mProtoReceiptQuery.transactionid();
|
||||
transaction_id = target->getTransactionId();
|
||||
}
|
||||
|
||||
TransactionGetReceiptQuery::~TransactionGetReceiptQuery()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H
|
||||
|
||||
#include "QueryHeader.h"
|
||||
#include "proto/hedera/TransactionGetReceipt.pb.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionGetReceiptQuery
|
||||
{
|
||||
public:
|
||||
TransactionGetReceiptQuery(Poco::AutoPtr<QueryHeader> queryHeader, const Transaction* target);
|
||||
~TransactionGetReceiptQuery();
|
||||
|
||||
proto::TransactionGetReceiptQuery* getProto() { return &mProtoReceiptQuery; }
|
||||
|
||||
const std::string& getConnectionString() const { return mQueryHeader->getConnectionString(); }
|
||||
|
||||
protected:
|
||||
Poco::AutoPtr<QueryHeader> mQueryHeader;
|
||||
proto::TransactionGetReceiptQuery mProtoReceiptQuery;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H
|
||||
@ -1,47 +0,0 @@
|
||||
#include "TransactionId.h"
|
||||
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionId::TransactionId()
|
||||
: shard(0), realm(0), num(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionId::TransactionId(const proto::TransactionID& transaction)
|
||||
{
|
||||
auto account_id = transaction.accountid();
|
||||
shard = account_id.shardnum();
|
||||
realm = account_id.realmnum();
|
||||
num = account_id.accountnum();
|
||||
mTransactionValidStart = DataTypeConverter::convertFromProtoTimestamp(transaction.transactionvalidstart());
|
||||
|
||||
}
|
||||
|
||||
TransactionId::TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart)
|
||||
: shard(shard), realm(realm), num(num), mTransactionValidStart(transactionValidStart)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionId::~TransactionId()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::JSON::Object::Ptr TransactionId::convertToJSON()
|
||||
{
|
||||
Poco::JSON::Object::Ptr result = new Poco::JSON::Object;
|
||||
result->set("transactionValidStart", mTransactionValidStart);
|
||||
Poco::JSON::Object accountId;
|
||||
accountId.set("shard", shard);
|
||||
accountId.set("realm", realm);
|
||||
accountId.set("num", num);
|
||||
result->set("accountId", accountId);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 02.09.20
|
||||
*
|
||||
* @brief: class for composing hedera transaction
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proto/hedera/BasicTypes.pb.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionId
|
||||
{
|
||||
public:
|
||||
TransactionId();
|
||||
TransactionId(const proto::TransactionID& transaction);
|
||||
TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart);
|
||||
~TransactionId();
|
||||
|
||||
Poco::JSON::Object::Ptr convertToJSON();
|
||||
|
||||
protected:
|
||||
Poco::Timestamp mTransactionValidStart;
|
||||
union {
|
||||
struct {
|
||||
int shard;
|
||||
int realm;
|
||||
int num;
|
||||
};
|
||||
int val[3];
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H
|
||||
@ -1,25 +0,0 @@
|
||||
#include "TransactionReceipt.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
TransactionReceipt::TransactionReceipt(const proto::TransactionReceipt& protoReceipt)
|
||||
: mProtoReceipt(protoReceipt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionReceipt::~TransactionReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemoryBin* TransactionReceipt::getRunningHash()
|
||||
{
|
||||
auto hash = mProtoReceipt.topicrunninghash();
|
||||
auto hashBin = MemoryManager::getInstance()->getFreeMemory(hash.size());
|
||||
memcpy(*hashBin, hash.data(), hash.size());
|
||||
return hashBin;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H
|
||||
|
||||
#include "../proto/hedera/TransactionReceipt.pb.h"
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionReceipt
|
||||
{
|
||||
public:
|
||||
TransactionReceipt(const proto::TransactionReceipt& protoReceipt);
|
||||
~TransactionReceipt();
|
||||
|
||||
proto::TopicID getTopicId() { return mProtoReceipt.topicid(); }
|
||||
google::protobuf::uint64 getSequenceNumber() { return mProtoReceipt.topicsequencenumber(); }
|
||||
google::protobuf::uint64 getRunningHashVersion() { return mProtoReceipt.topicrunninghashversion(); }
|
||||
//! caller must release memory after finish with it
|
||||
MemoryBin* getRunningHash();
|
||||
proto::ResponseCodeEnum getStatus() { return mProtoReceipt.status(); }
|
||||
|
||||
inline proto::TransactionReceipt* getProto() { return &mProtoReceipt; }
|
||||
|
||||
protected:
|
||||
proto::TransactionReceipt mProtoReceipt;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H
|
||||
@ -1,12 +0,0 @@
|
||||
#include "TransactionRecord.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionRecord::TransactionRecord(const proto::TransactionRecord& transaction_record)
|
||||
: mProtoRecord(transaction_record)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECORD_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECORD_H
|
||||
|
||||
#include "proto/hedera/TransactionRecord.pb.h"
|
||||
|
||||
namespace model
|
||||
{
|
||||
namespace hedera
|
||||
{
|
||||
class TransactionRecord
|
||||
{
|
||||
public:
|
||||
TransactionRecord(const proto::TransactionRecord& transaction_record);
|
||||
|
||||
|
||||
inline proto::TransactionRecord* getProto() { return &mProtoRecord; }
|
||||
|
||||
protected:
|
||||
proto::TransactionRecord mProtoRecord;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECORD_H
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
#include "TransactionResponse.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
TransactionResponse::TransactionResponse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionResponse::~TransactionResponse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
#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
|
||||
@ -1,169 +0,0 @@
|
||||
#include "CryptoKey.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
CryptoKey::CryptoKey()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CryptoKey::CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType)
|
||||
: mKeyType(keyType)
|
||||
{
|
||||
if (!privateKey) {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
} else {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB(*privateKey, privateKey->size()));
|
||||
}
|
||||
|
||||
if (!publicKey) {
|
||||
mPublicKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
} else {
|
||||
mPublicKey = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB(*publicKey, publicKey->size()));
|
||||
}
|
||||
}
|
||||
|
||||
CryptoKey::~CryptoKey()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string CryptoKey::toString()
|
||||
{
|
||||
assert(mKeyType < KEY_TYPE_COUNT && mKeyType >= 0);
|
||||
std::stringstream ss;
|
||||
ss << "Key Type: " << typeToString(static_cast<KeyType>(mKeyType)) << std::endl;
|
||||
ss << "Public Key: " << DataTypeConverter::binToHex(mPublicKey);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
const char* CryptoKey::typeToString(KeyType type)
|
||||
{
|
||||
switch (type) {
|
||||
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 "<unknown type>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void CryptoKey::setPrivateKey(const MemoryBin* privateKey)
|
||||
{
|
||||
if (!privateKey) {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
}
|
||||
else {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>(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);
|
||||
|
||||
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 CryptoKey::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where public_key = ?"
|
||||
, into(mID), use(mPublicKey);
|
||||
return select;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::Statement CryptoKey::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (private_key, public_key, crypto_key_type_id) VALUES(?,?,?)"
|
||||
, use(mPrivateKey), use(mPublicKey), use(mKeyType);
|
||||
return insert;
|
||||
}
|
||||
|
||||
size_t CryptoKey::updatePrivkeyAndKeyType()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
#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"
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
enum KeyType {
|
||||
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
|
||||
};
|
||||
|
||||
class CryptoKey : public ModelBase
|
||||
{
|
||||
public:
|
||||
CryptoKey();
|
||||
CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType);
|
||||
~CryptoKey();
|
||||
|
||||
// generic db operations
|
||||
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(); }
|
||||
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<unsigned char>& 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);
|
||||
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
Poco::Nullable<Poco::Data::BLOB> mPrivateKey;
|
||||
Poco::Nullable<Poco::Data::BLOB> mPublicKey;
|
||||
int mKeyType;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE
|
||||
@ -1,135 +0,0 @@
|
||||
#include "HederaAccount.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
HederaAccount::HederaAccount()
|
||||
: 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*/, ServerConfig::HederaNetworkType type /*= ServerConfig::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>()), mType(tuple.get<5>()), mUpdated(tuple.get<6>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaAccount::~HederaAccount()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string HederaAccount::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 << "Hedera Net Type: " << hederaNetworkTypeToString((ServerConfig::HederaNetworkType)mType) << std::endl;
|
||||
ss << "last update: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string HederaAccount::getBalanceString()
|
||||
{
|
||||
char buffer[65]; memset(buffer, 0, 65);
|
||||
//100,000,000
|
||||
#ifdef _WIN32
|
||||
sprintf_s(buffer, 64, "%.8f HBAR", (double)(mBalance) / 100000000.0);
|
||||
#else
|
||||
sprintf(buffer, "%.8f HBAR", (double)(mBalance) / 100000000.0);
|
||||
#endif
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
|
||||
const char* HederaAccount::hederaNetworkTypeToString(ServerConfig::HederaNetworkType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ServerConfig::HEDERA_MAINNET: return "Mainnet";
|
||||
case ServerConfig::HEDERA_TESTNET: return "Testnet";
|
||||
case ServerConfig::HEDERA_UNKNOWN: return "unknown";
|
||||
default: return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
ServerConfig::HederaNetworkType HederaAccount::hederaNetworkTypeFromString(const std::string& typeString)
|
||||
{
|
||||
if ("MAINNET" == typeString || "Mainnet" == typeString) {
|
||||
return ServerConfig::HEDERA_MAINNET;
|
||||
}
|
||||
if ("TESTNET" == typeString || "Testnet" == typeString) {
|
||||
return ServerConfig::HEDERA_TESTNET;
|
||||
}
|
||||
return ServerConfig::HEDERA_UNKNOWN;
|
||||
}
|
||||
|
||||
NodeServerType HederaAccount::networkTypeToNodeServerType(ServerConfig::HederaNetworkType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ServerConfig::HEDERA_MAINNET: return NODE_SERVER_HEDERA_MAINNET_NODE;
|
||||
case ServerConfig::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);
|
||||
|
||||
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(mType), into(mUpdated);
|
||||
|
||||
return select;
|
||||
|
||||
}
|
||||
|
||||
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, network_type, updated FROM " << getTableName()
|
||||
<< " where " << fieldName << " LIKE ?";
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaAccount::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where account_hedera_id = ?"
|
||||
, into(mID), use(mAccountHederaId);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaAccount::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (user_id, account_hedera_id, account_key_id, balance, network_type) VALUES(?,?,?,?,?)"
|
||||
, use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance), use(mType);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE
|
||||
|
||||
//#include "ModelBase.h"
|
||||
#include "../../ServerConfig.h"
|
||||
#include "Poco/Tuple.h"
|
||||
|
||||
#include "NodeServer.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
typedef Poco::Tuple<int, int, int, int, Poco::UInt64, int, Poco::DateTime> HederaAccountTuple;
|
||||
|
||||
|
||||
|
||||
class HederaAccount : public ModelBase
|
||||
{
|
||||
public:
|
||||
HederaAccount();
|
||||
HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, ServerConfig::HederaNetworkType type = ServerConfig::HEDERA_MAINNET);
|
||||
HederaAccount(const HederaAccountTuple& tuple);
|
||||
~HederaAccount();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() const { return "hedera_accounts"; }
|
||||
std::string toString();
|
||||
|
||||
|
||||
static const char* hederaNetworkTypeToString(ServerConfig::HederaNetworkType type);
|
||||
static NodeServerType networkTypeToNodeServerType(ServerConfig::HederaNetworkType type);
|
||||
static ServerConfig::HederaNetworkType hederaNetworkTypeFromString(const std::string& typeString);
|
||||
|
||||
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; }
|
||||
std::string getBalanceString();
|
||||
|
||||
inline ServerConfig::HederaNetworkType getNetworkType() { return (ServerConfig::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);
|
||||
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;
|
||||
int mType;
|
||||
Poco::DateTime mUpdated;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE
|
||||
@ -1,100 +0,0 @@
|
||||
#include "HederaId.h"
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaId::HederaId(const HederaIdTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()),
|
||||
mShardNum(tuple.get<1>()), mRealmNum(tuple.get<2>()), mNum(tuple.get<3>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaId::~HederaId()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string HederaId::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
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<Poco::Mutex> _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)
|
||||
{
|
||||
|
||||
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 HederaId::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where shardNum = ? AND realmNum = ? AND num = ?"
|
||||
, into(mID), use(mShardNum), use(mRealmNum), use(mNum);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaId::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (shardNum, realmNum, num) VALUES(?,?,?)"
|
||||
, use(mShardNum), use(mRealmNum), use(mNum);
|
||||
|
||||
return insert;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
#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 {
|
||||
|
||||
typedef Poco::Tuple<int, Poco::UInt64, Poco::UInt64, Poco::UInt64> 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
|
||||
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();
|
||||
|
||||
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);
|
||||
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
|
||||
@ -1,113 +0,0 @@
|
||||
#include "HederaTopic.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
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 HederaTopicTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()), mTopicHederaId(tuple.get<1>()), mName(tuple.get<2>()), mAutoRenewAccountHederaId(tuple.get<3>()),
|
||||
mAutoRenewPeriod(tuple.get<4>()), mGroupId(tuple.get<5>()), mAdminKeyId(tuple.get<6>()), mSubmitKeyId(tuple.get<7>()),
|
||||
mCurrentTimeout(tuple.get<8>()), mSequenceNumber(tuple.get<9>()), mUpdated(tuple.get<10>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaTopic::HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId)
|
||||
: mTopicHederaId(0), mName(name), mAutoRenewAccountHederaId(autoRenewAccountId), mAutoRenewPeriod(autoRenewPeriod), mGroupId(groupId),
|
||||
mAdminKeyId(0), mSubmitKeyId(0), mSequenceNumber(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaTopic::~HederaTopic()
|
||||
{
|
||||
}
|
||||
|
||||
std::string HederaTopic::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::endl;
|
||||
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;
|
||||
ss << "Admin Key id: " << std::to_string(mAdminKeyId) << std::endl;
|
||||
ss << "Submit Key id: " << std::to_string(mSubmitKeyId) << std::endl;
|
||||
ss << "Hedera Topic Timeout: " << 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();
|
||||
}
|
||||
|
||||
std::string HederaTopic::getAutoRenewPeriodString() const
|
||||
{
|
||||
return secondsToReadableDuration(mAutoRenewPeriod) + " (" + std::to_string(mAutoRenewPeriod) + " seconds)";
|
||||
}
|
||||
|
||||
std::string HederaTopic::getCurrentTimeoutString() const
|
||||
{
|
||||
return Poco::DateTimeFormatter::format(mCurrentTimeout, "%Y-%m-%d %H:%M:%S");
|
||||
}
|
||||
std::string HederaTopic::getUpdatedString() const
|
||||
{
|
||||
return Poco::DateTimeFormatter::format(mUpdated, "%Y-%m-%d %H:%M:%S");
|
||||
}
|
||||
|
||||
Poco::Data::Statement HederaTopic::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
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(mName), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod)
|
||||
, into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated);
|
||||
|
||||
return select;
|
||||
|
||||
}
|
||||
Poco::Data::Statement HederaTopic::_loadAllFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
//typedef Poco::Tuple<int, int, std::string, int, Poco::UInt32, int, int, int, Poco::DateTime, Poco::UInt64, Poco::DateTime> HederaTopicTuple;
|
||||
|
||||
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();
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaTopic::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where topic_hedera_id = ? "
|
||||
<< " AND name = ? "
|
||||
, into(mID), use(mTopicHederaId), use(mName);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaTopic::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (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(mName), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod)
|
||||
, use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user