From 5af588f6bda4f52af7bc07d7fffc6f6efc8e13b3 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Mon, 18 Jan 2021 14:55:51 +0100 Subject: [PATCH] finish test page for node server test --- .../HTTPInterface/AdminNodeServerTestPage.cpp | 318 ++++++++++++++---- src/cpp/lib/DataTypeConverter.cpp | 60 ++++ src/cpp/lib/DataTypeConverter.h | 6 + src/cpp/lib/JsonRPCRequest.cpp | 145 ++++++++ src/cpp/lib/JsonRPCRequest.h | 30 ++ src/cpp/lib/JsonRequest.cpp | 1 + src/cpp/model/gradido/Transaction.cpp | 23 +- src/cpp/model/gradido/Transaction.h | 3 +- src/cpsp/adminNodeServerTest.cpsp | 157 +++++++-- 9 files changed, 662 insertions(+), 81 deletions(-) create mode 100644 src/cpp/lib/JsonRPCRequest.cpp create mode 100644 src/cpp/lib/JsonRPCRequest.h diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp index 5390904e7..d37c1c36c 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp @@ -13,14 +13,18 @@ #include "../controller/HederaTopic.h" #include "../lib/DataTypeConverter.h" #include "../lib/Profiler.h" +#include "../lib/JsonRPCRequest.h" #include "../model/gradido/Transaction.h" #include "Poco/Thread.h" +#include "Poco/DateTime.h" +#include "Poco/JSON/Stringifier.h" enum PageType { PAGE_CHOOSE_TEST, - PAGE_RUN_4_SET_TEST + PAGE_RUN_4_SET_TEST, + PAGE_GET_TRANSACTION_RPC_CALL }; #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp" @@ -36,7 +40,7 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 24 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 28 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" const char* pageName = "Node Server Test"; PageType page = PAGE_CHOOSE_TEST; @@ -45,6 +49,8 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::AutoPtr hedera_topic; int hedera_timeout = 15; + bool steps[6]; memset(steps, 0, 6 * sizeof(bool)); + if(!form.empty()) { @@ -69,6 +75,17 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques auto submit = form.get("submit", ""); if(submit == "Run 4-Test") { page = PAGE_RUN_4_SET_TEST; + } else if(submit == "json-rpc getTransactions") { + page = PAGE_GET_TRANSACTION_RPC_CALL; + } + std::string step_temp; + for(int i = 0; i < 6; i++) { + std::string name = "step-"; + name += std::to_string(i+2); + step_temp = form.get(name, ""); + if(step_temp == "1") { + steps[i] = true; + } } } @@ -143,82 +160,84 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 63 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 80 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; responseStream << "\t\n"; responseStream << "\t
\n"; responseStream << "\t \n"; + responseStream << "\t \n"; responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t

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

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

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

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

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

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

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

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

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

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

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

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

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

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

7. Ask choosen node for transaction and print result

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

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

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

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

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

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

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

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

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

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

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

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

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

7. Ask choosen node for transaction and print result

\n"; + responseStream << "\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t"; -#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 102 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(node_servers.size() == 0) { responseStream << "\n"; responseStream << "\t\t\t\t\tEdit Node-Servers\n"; responseStream << "\t\t\t\t"; -#line 85 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 104 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t"; -#line 94 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 113 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(hedera_topics.size() == 0) { responseStream << "\n"; responseStream << "\t\t\t\t\tEdit Hedera-Topics\n"; responseStream << "\t\t\t\t"; -#line 96 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 115 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t seconds \n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; + responseStream << "\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

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

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

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

    \n"; responseStream << "\t\t\t"; -#line 118 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 158 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" Profiler time2; auto group_id = hedera_topic->getModel()->getGroupId(); @@ -285,62 +355,194 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques user_2->login(password2); responseStream << "\t\t\t\n"; responseStream << "\t\t\t

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

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

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

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

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

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

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

    \n"; responseStream << "\t\t\t"; -#line 144 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); - { - auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); - transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); - transaction1->sign(user_1); - } + if(!steps[0]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

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

    "; +#line 194 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction1->getTransactionAsJson(true)) ); + responseStream << "

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

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

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

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

    \n"; responseStream << "\t\t\t"; -#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); - { - auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); - transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); - transaction2->sign(user_2); - transaction2->sign(user_1); - } - + if(!steps[1]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 204 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); + transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(3); + transaction2->sign(user_2); + transaction2->sign(user_1); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 211 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction2->getTransactionAsJson(true)) ); + responseStream << "

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

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

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

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

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

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction3 = model::gradido::Transaction::createCreation(user_2, 1000, Poco::DateTime(), "Test Creation"); + transaction3->sign(user_1); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction3->getTransactionAsJson(true)) ); + responseStream << "

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

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

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

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

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

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 235 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); + auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 500, "Test Transfer"); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 239 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction4[0]->getTransactionAsJson(true)) ); + responseStream << "

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

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

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

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

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

    skipped

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

    7. Ask choosen node for transaction and print result

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

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 255 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto node_server_model = node_server->getModel(); + JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); + Poco::JSON::Object params; + params.set("groupAlias", user_group->getModel()->getAlias()); + params.set("lastKnownSequenceNumber", 0); + auto gn_answear = jsonrpc.request("getTransactions", params); + if(!gn_answear.isNull()) { + std::stringstream ss; + Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); responseStream << "\n"; + responseStream << "\t\t\t\t\t"; +#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(ss.str()) ); +#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } + } responseStream << "\n"; + responseStream << "\t\t
  • \n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; +#line 270 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { + auto node_server_model = node_server->getModel(); + auto user_group = controller::Group::load(node_server_model->getGroupId()); + JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); + Poco::JSON::Object params; + params.set("groupAlias", user_group->getModel()->getAlias()); + params.set("lastKnownSequenceNumber", 0); + auto gn_answear = jsonrpc.request("getTransactions", params); + if(!gn_answear.isNull()) { + std::stringstream ss; + Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); + //printf("result: %s\n", ss.str().data()); responseStream << "\n"; + responseStream << "\t\t\t"; +#line 282 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(ss.str()) ); +#line 282 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } + } responseStream << "\n"; responseStream << "\t\n"; responseStream << "
\n"; responseStream << "\n"; // begin include footer.cpsp diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index e83663551..6c56bdef2 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -1,5 +1,7 @@ #include "DataTypeConverter.h" +#include "Poco/RegularExpression.h" + #include #include "sodium.h" #include @@ -9,6 +11,8 @@ namespace DataTypeConverter { + Poco::RegularExpression g_rexExpBase64("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"); + NumberParseState strToInt(const std::string& input, int& result) { try { @@ -327,4 +331,60 @@ namespace DataTypeConverter { return Poco::Timespan(duration.seconds(), 0); } + + int replaceBase64WithHex(Poco::JSON::Object::Ptr json) + { + //g_rexExpBase64 + auto mm = MemoryManager::getInstance(); + int count_replacements = 0; + + for (auto it = json->begin(); it != json->end(); it++) + { + if (it->first == "sigPair") + { + int zahl = 1; + } + if (json->isObject(it)) { + auto local_json = it->second.extract(); + count_replacements += replaceBase64WithHex(local_json); + json->set(it->first, local_json); + } + else if (json->isArray(it)) { + + } + else if (it->second.isString()) + { + auto field_value = it->second.extract(); + if(!g_rexExpBase64.match(field_value)) continue; + + auto bin = base64ToBin(field_value); + if(!bin) continue; + + auto hex = binToHex(bin); + mm->releaseMemory(bin); + json->set(it->first, hex); + count_replacements++; + } + } + + return count_replacements; + } + + 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, "
"); + } + pos = 0; + while ((pos = in.find("\n", pos)) != std::string::npos) { + in.replace(pos, 1, "
"); + } + pos = 0; + while ((pos = in.find(" ", pos)) != std::string::npos) { + in.replace(pos, 1, " "); + } + return in; + } } \ No newline at end of file diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index ede606666..1adc0f14b 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -7,6 +7,7 @@ #include "Poco/Timespan.h" #include "Poco/Nullable.h" #include "Poco/Data/LOB.h" +#include "Poco/JSON/Object.h" #include "../SingletonManager/LanguageManager.h" #include "../proto/hedera/Timestamp.pb.h" @@ -58,6 +59,11 @@ namespace DataTypeConverter { void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::gradido::Timestamp* protoTimestamp); Poco::Timestamp convertFromProtoTimestampSeconds(const proto::gradido::TimestampSeconds& timestampSeconds); 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 + int replaceBase64WithHex(Poco::JSON::Object::Ptr json); + std::string replaceNewLineWithBr(std::string& in); }; #endif // __GRADIDO_LOGIN_SERVER_LIB_DATA_TYPE_CONVERTER_H diff --git a/src/cpp/lib/JsonRPCRequest.cpp b/src/cpp/lib/JsonRPCRequest.cpp new file mode 100644 index 000000000..1d4637fea --- /dev/null +++ b/src/cpp/lib/JsonRPCRequest.cpp @@ -0,0 +1,145 @@ +#include "JsonRPCRequest.h" + +#include "Profiler.h" + + +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" +#include "Poco/JSON/Parser.h" + +#include "sodium.h" +#include "../SingletonManager/MemoryManager.h" +#include "DataTypeConverter.h" + + +JsonRPCRequest::JsonRPCRequest(const std::string& serverHost, int serverPort) + : JsonRequest(serverHost, serverPort) +{ + + if (serverHost.find("http://") != serverHost.npos) { + mServerHost = serverHost.substr(7); + } + else if (serverHost.find("https://") != serverHost.npos) { + mServerHost = serverHost.substr(8); + } +} + +JsonRPCRequest::~JsonRPCRequest() +{ + +} + +Poco::JSON::Object::Ptr JsonRPCRequest::request(const char* methodName, const Poco::JSON::Object& params) +{ + static const char* functionName = "JsonRequest::request"; + + //requestJson.set("user", std::string(mSessionUser->getPublicKeyHex())); + + // send post request via https + // 443 = HTTPS Default + // TODO: adding port into ServerConfig + try { + Profiler phpRequestTime; + + Poco::SharedPtr clientSession; + if (mServerPort == 443) { + clientSession = new Poco::Net::HTTPSClientSession(mServerHost, mServerPort); + } + else { + clientSession = new Poco::Net::HTTPClientSession(mServerHost, mServerPort); + } + //Poco::Net::HTTPSClientSession httpsClientSession(mServerHost, mServerPort); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/", "HTTP/1.1"); + //request.setContentType("application/json"); + + Poco::JSON::Object requestJson; + + requestJson.set("jsonrpc", "2.0"); + requestJson.set("id", rand()); + requestJson.set("method", methodName); + requestJson.set("params", params); + + request.setChunkedTransferEncoding(true); + std::ostream& request_stream = clientSession->sendRequest(request); + requestJson.stringify(request_stream); + + Poco::Net::HTTPResponse response; + std::istream& response_stream = clientSession->receiveResponse(response); + + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(response_stream, line); ) { + responseStringStream << line << std::endl; + } + Poco::Logger& speedLog = Poco::Logger::get("SpeedLog"); + std::string method_name(methodName); + speedLog.information("[%s] node server time: %s", method_name, phpRequestTime.string()); + + if (responseStringStream.str().size() == 0) { + addError(new Error(functionName, "empty request answer")); + addError(new ParamError(functionName, "server host: ", mServerHost)); + addError(new ParamError(functionName, "server port", mServerPort)); + addError(new ParamError(functionName, "method: ", methodName)); + sendErrorsAsEmail(); + return nullptr; + } + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + } + catch (Poco::Exception& ex) { + addError(new ParamError(functionName, "error parsing request answer", ex.displayText().data())); + + std::string fileName = "node_response_"; + fileName += methodName; + fileName += ".html"; + + FILE* f = fopen(fileName.data(), "wt"); + if (f) { + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + } + // */ + sendErrorsAsEmail(responseStringStream.str()); + return nullptr; + } + + auto object = parsedJson.extract(); + auto result = object->getObject("result"); + auto state = result->get("state"); + + std::string stateString = state.convert(); + if (stateString == "error") { + addError(new Error(functionName, "node server return error")); + if (!result->isNull("msg")) { + addError(new ParamError(functionName, "msg:", result->get("msg").convert().data())); + } + if (!result->isNull("details")) { + addError(new ParamError(functionName, "details:", result->get("details").convert().data())); + } + sendErrorsAsEmail(); + return nullptr; + } + else if (stateString == "success") { + /*for (auto it = result->begin(); it != result->end(); it++) { + std::string index = it->first; + std::string value = it->second.toString(); + printf("[JsonRequest] %s: %s\n", index.data(), value.data()); + }*/ + return object; + } + } + catch (Poco::Exception& e) { + addError(new ParamError(functionName, "connect error to node server", e.displayText().data())); + sendErrorsAsEmail(); + return nullptr; + } + + return nullptr; +} \ No newline at end of file diff --git a/src/cpp/lib/JsonRPCRequest.h b/src/cpp/lib/JsonRPCRequest.h new file mode 100644 index 000000000..a69e8e07d --- /dev/null +++ b/src/cpp/lib/JsonRPCRequest.h @@ -0,0 +1,30 @@ +/*! + * + * \author: Dario Rekowski + * + * \date: 13.01.2021 + * + * \brief: Class for Json Requests to php server + * +*/ + +#include "JsonRequest.h" + +#ifndef __GRADIDO_LOGIN_SERVER_LIB_JSON_RPC_REQUEST_ +#define __GRADIDO_LOGIN_SERVER_LIB_JSON_RPC_REQUEST_ + + +class JsonRPCRequest : public JsonRequest +{ +public: + JsonRPCRequest(const std::string& serverHost, int serverPort); + ~JsonRPCRequest(); + + Poco::JSON::Object::Ptr request(const char* methodName, const Poco::JSON::Object& params); + +protected: + +}; + + +#endif //__GRADIDO_LOGIN_SERVER_LIB_JSON_RPC_REQUEST_ \ No newline at end of file diff --git a/src/cpp/lib/JsonRequest.cpp b/src/cpp/lib/JsonRequest.cpp index a59b0cc7a..ed3448b31 100644 --- a/src/cpp/lib/JsonRequest.cpp +++ b/src/cpp/lib/JsonRequest.cpp @@ -90,6 +90,7 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::JSON: addError(new ParamError(functionName, "cakePHP Exception: ", message.toString())); addError(new ParamError(functionName, "calling: ", methodName)); + addError(new ParamError(functionName, "for server host: ", mServerHost)); std::string fields[] = { "url", "code", "file", "line" }; for (int i = 0; i < 4; i++) { auto field = fields[i]; diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index a5ccd21a4..6fa4b1446 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -9,12 +9,16 @@ #include "../../controller/HederaAccount.h" #include "../../controller/HederaRequest.h" +#include "../lib/DataTypeConverter.h" + #include "../hedera/Transaction.h" #include "../../tasks/HederaTask.h" #include +#include "Poco/JSON/Parser.h" + #include @@ -594,7 +598,7 @@ namespace model { } - std::string Transaction::getTransactionAsJson() + std::string Transaction::getTransactionAsJson(bool replaceBase64WithHex/* = false*/) { static const char* function_name = "Transaction::getTransactionAsJson"; std::string json_message = ""; @@ -622,6 +626,23 @@ namespace model { json_message.replace(startBodyBytes, endCur - startBodyBytes, json_message_body); //printf("json: %s\n", json_message.data()); + if (replaceBase64WithHex) { + Poco::JSON::Parser json_parser; + try { + auto json = json_parser.parse(json_message); + Poco::JSON::Object::Ptr object = json.extract(); + if (DataTypeConverter::replaceBase64WithHex(object)) { + std::ostringstream oss; + Poco::JSON::Stringifier::stringify(json, oss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); + json_message = oss.str(); + } + } + catch (Poco::Exception& ex) { + addError(new ParamError(function_name, "exception by parsing or printing json", ex.message())); + addError(new ParamError(function_name, "pending task id: ", getModel()->getID())); + } + } + return json_message; } diff --git a/src/cpp/model/gradido/Transaction.h b/src/cpp/model/gradido/Transaction.h index 8ff5715c4..ee27a9719 100644 --- a/src/cpp/model/gradido/Transaction.h +++ b/src/cpp/model/gradido/Transaction.h @@ -58,9 +58,10 @@ namespace model { //! \return true if at least one sign is missing and user isn't forbidden and isn't required bool needSomeoneToSign(Poco::AutoPtr user); + std::string getTransactionAsJson(bool replaceBase64WithHex = false); + protected: - std::string getTransactionAsJson(); Poco::AutoPtr mTransactionBody; proto::gradido::GradidoTransaction mProtoTransaction; diff --git a/src/cpsp/adminNodeServerTest.cpsp b/src/cpsp/adminNodeServerTest.cpsp index 08325ae04..ace5eb4e7 100644 --- a/src/cpsp/adminNodeServerTest.cpsp +++ b/src/cpsp/adminNodeServerTest.cpsp @@ -10,14 +10,18 @@ #include "../controller/HederaTopic.h" #include "../lib/DataTypeConverter.h" #include "../lib/Profiler.h" +#include "../lib/JsonRPCRequest.h" #include "../model/gradido/Transaction.h" #include "Poco/Thread.h" +#include "Poco/DateTime.h" +#include "Poco/JSON/Stringifier.h" enum PageType { PAGE_CHOOSE_TEST, - PAGE_RUN_4_SET_TEST + PAGE_RUN_4_SET_TEST, + PAGE_GET_TRANSACTION_RPC_CALL }; %> @@ -29,6 +33,8 @@ enum PageType Poco::AutoPtr hedera_topic; int hedera_timeout = 15; + bool steps[6]; memset(steps, 0, 6 * sizeof(bool)); + if(!form.empty()) { @@ -53,6 +59,17 @@ enum PageType auto submit = form.get("submit", ""); if(submit == "Run 4-Test") { page = PAGE_RUN_4_SET_TEST; + } else if(submit == "json-rpc getTransactions") { + page = PAGE_GET_TRANSACTION_RPC_CALL; + } + std::string step_temp; + for(int i = 0; i < 6; i++) { + std::string name = "step-"; + name += std::to_string(i+2); + step_temp = form.get(name, ""); + if(step_temp == "1") { + steps[i] = true; + } } } @@ -65,20 +82,22 @@ enum PageType
+

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

-

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

-

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

-

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

-

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

-

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

-

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

-

7. Ask choosen node for transaction and print result

+

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

+

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

+

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

+

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

+

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

+

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

+

7. Ask choosen node for transaction and print result

+ <% if(node_servers.size() == 0) { %> Edit Node-Servers @@ -111,6 +130,27 @@ enum PageType
+
+
+

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

+
+
+ + <% if(node_servers.size() == 0) { %> + Edit Node-Servers + <% } %> + + +
+
+
<% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %>
  • @@ -143,30 +183,105 @@ enum PageType

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

    <% time2.reset(); - { - auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); - transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); - transaction1->sign(user_1); - } + if(!steps[0]) { %> +

    skipped

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

    <%= DataTypeConverter::replaceNewLineWithBr(transaction1->getTransactionAsJson(true)) %>

    + <% } %>

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

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

    <% time2.reset(); - { - auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); - transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); - transaction2->sign(user_2); - transaction2->sign(user_1); - } - + if(!steps[1]) { %> +

    skipped

    + <% } else { + auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); + transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(3); + transaction2->sign(user_2); + transaction2->sign(user_1); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction2->getTransactionAsJson(true)) %>

    + <% } %>

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

  • +
  • +

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

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

    skipped

    + <% } else { + auto transaction3 = model::gradido::Transaction::createCreation(user_2, 1000, Poco::DateTime(), "Test Creation"); + transaction3->sign(user_1); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction3->getTransactionAsJson(true)) %>

    + <% } %> +

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

    +
  • +
  • +

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

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

    skipped

    + <% } else { + auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); + auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 500, "Test Transfer"); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction4[0]->getTransactionAsJson(true)) %>

    + <% } %> +

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

    +
  • +
  • +

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

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

    skipped

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

    7. Ask choosen node for transaction and print result

    + <% if(!steps[3] || node_server.isNull()) { %> +

    skipped

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