From fea4f034f4eef875a2f9ccd28937c9e20c8cce84 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 12 Oct 2020 17:07:43 +0200 Subject: [PATCH] work on gradido transaction wrapper classes, update ProcessingTransaction (move TransactionBody in own class) and all using it --- .../HTTPInterface/CheckTransactionPage.cpp | 21 ++-- .../HTTPInterface/PassphrasedTransaction.cpp | 25 ++-- .../HTTPInterface/PassphrasedTransaction.cpsp | 3 +- .../HTTPInterface/RepairDefectPassphrase.cpp | 4 +- src/cpp/SingletonManager/SessionManager.cpp | 1 + src/cpp/SingletonManager/SessionManager.h | 1 + src/cpp/lib/DataTypeConverter.cpp | 10 +- src/cpp/lib/DataTypeConverter.h | 2 +- src/cpp/model/gradido/GroupMemberUpdate.cpp | 48 ++++++++ src/cpp/model/gradido/GroupMemberUpdate.h | 22 ++++ src/cpp/model/gradido/ManageNodeBody.cpp | 0 src/cpp/model/gradido/ManageNodeBody.h | 10 ++ src/cpp/model/gradido/TransactionBase.h | 1 + src/cpp/model/gradido/TransactionBody.cpp | 114 ++++++++++++++++++ src/cpp/model/gradido/TransactionBody.h | 56 +++++++++ src/cpp/tasks/ProcessingTransaction.cpp | 87 +++---------- src/cpp/tasks/ProcessingTransaction.h | 31 ++--- src/cpp/tasks/SigningTransaction.cpp | 5 +- src/cpsp/PassphrasedTransaction.cpsp | 3 +- src/cpsp/checkTransaction.cpsp | 21 ++-- src/cpsp/repairDefectPassphrase.cpsp | 4 +- 21 files changed, 339 insertions(+), 130 deletions(-) create mode 100644 src/cpp/model/gradido/GroupMemberUpdate.cpp create mode 100644 src/cpp/model/gradido/GroupMemberUpdate.h create mode 100644 src/cpp/model/gradido/ManageNodeBody.cpp create mode 100644 src/cpp/model/gradido/ManageNodeBody.h create mode 100644 src/cpp/model/gradido/TransactionBody.cpp create mode 100644 src/cpp/model/gradido/TransactionBody.h diff --git a/src/cpp/HTTPInterface/CheckTransactionPage.cpp b/src/cpp/HTTPInterface/CheckTransactionPage.cpp index ce521c7e2..5f72ce565 100644 --- a/src/cpp/HTTPInterface/CheckTransactionPage.cpp +++ b/src/cpp/HTTPInterface/CheckTransactionPage.cpp @@ -126,15 +126,22 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, } return; } - auto processingTransaction = mSession->getNextReadyTransaction(¬ReadyTransactions); + // skip transactions with errors + Poco::AutoPtr processingTransaction; + Poco::AutoPtr transaction_body; + do { + processingTransaction = mSession->getNextReadyTransaction(¬ReadyTransactions); + transaction_body = processingTransaction->getTransactionBody(); + } while(!processingTransaction.isNull() && transaction_body.isNull()); + if(sumTransactions > 0) { enableLogout = false; } - if(PAGE_NO_TRANSACTIONS == state && !processingTransaction.isNull()) { - auto transactionType = processingTransaction->getType(); + if(PAGE_NO_TRANSACTIONS == state && !processingTransaction.isNull() && !transaction_body.isNull()) { + auto transactionType = transaction_body->getType(); switch(transactionType) { - case TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; - case TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; + case model::gradido::TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; + case model::gradido::TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; } } @@ -352,7 +359,7 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t"; #line 161 "F:\\Gradido\\gradido_login_server_production\\src\\cpsp\\checkTransaction.cpsp" if(state == PAGE_TRANSACTION_TRANSFER) { - auto transferTransaction = processingTransaction->getTransferTransaction(); + auto transferTransaction = transaction_body->getTransferTransaction(); memo = transferTransaction->getMemo(); responseStream << "\n"; responseStream << "\t\t\t

"; @@ -400,7 +407,7 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t\t "; #line 182 "F:\\Gradido\\gradido_login_server_production\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_TRANSACTION_CREATION == state) { - auto creationTransaction = processingTransaction->getCreationTransaction(); + auto creationTransaction = transaction_body->getCreationTransaction(); auto transactionUser = creationTransaction->getUser(); memo = creationTransaction->getMemo(); responseStream << "\n"; diff --git a/src/cpp/HTTPInterface/PassphrasedTransaction.cpp b/src/cpp/HTTPInterface/PassphrasedTransaction.cpp index 9cca14642..05f3b034a 100644 --- a/src/cpp/HTTPInterface/PassphrasedTransaction.cpp +++ b/src/cpp/HTTPInterface/PassphrasedTransaction.cpp @@ -119,7 +119,8 @@ void PassphrasedTransaction::handleRequest(Poco::Net::HTTPServerRequest& request Poco::Thread::sleep(10); currentActiveTransaction = session->getNextReadyTransaction(); } - if(!currentActiveTransaction->isTransfer()) { + auto transaction_body = currentActiveTransaction->getTransactionBody(); + if(transaction_body.isNull() || !transaction_body->isTransfer()) { addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); } else { //auto signing = new SigningTransaction(currentActiveTransaction, user); @@ -218,39 +219,39 @@ void PassphrasedTransaction::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\n"; // end include header_old.cpsp responseStream << "\n"; -#line 138 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" if("" == errorString) { responseStream << "\n"; responseStream << "\t"; -#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 140 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" responseStream << ( errorString ); responseStream << "\n"; -#line 140 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 141 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" } responseStream << "\n"; responseStream << "

\n"; responseStream << "\t"; -#line 142 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\t"; -#line 143 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 144 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" if(PAGE_STATE_INPUT == state) { responseStream << "\n"; responseStream << "\t\n"; responseStream << "\t\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t

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

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

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

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

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

\n"; @@ -258,15 +259,15 @@ void PassphrasedTransaction::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t"; -#line 158 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 159 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" } else if(PAGE_STATE_SUCCESS == state) { responseStream << "\n"; responseStream << "\t\t

Gradidos wurden erfolgreich überwiesen.

\n"; responseStream << "\t\tWeitere Gradidos überweisen\n"; responseStream << "\t"; -#line 161 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" +#line 162 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\PassphrasedTransaction.cpsp" } responseStream << "\n"; responseStream << "
\n"; // begin include footer.cpsp diff --git a/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp b/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp index 8c360da79..ac772ceab 100644 --- a/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp +++ b/src/cpp/HTTPInterface/PassphrasedTransaction.cpsp @@ -103,7 +103,8 @@ enum PageState { Poco::Thread::sleep(10); currentActiveTransaction = session->getNextReadyTransaction(); } - if(!currentActiveTransaction->isTransfer()) { + auto transaction_body = currentActiveTransaction->getTransactionBody(); + if(transaction_body.isNull() || !transaction_body->isTransfer()) { addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); } else { //auto signing = new SigningTransaction(currentActiveTransaction, user); diff --git a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp index e089a38e2..5c988ba88 100644 --- a/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp +++ b/src/cpp/HTTPInterface/RepairDefectPassphrase.cpp @@ -160,11 +160,11 @@ void RepairDefectPassphrase::handleRequest(Poco::Net::HTTPServerRequest& request } else if(stateString == "success") { printf("[repairDefectPassphrase] request success, wait on transaction ready\n"); auto currentActiveTransaction = mSession->getNextReadyTransaction(); - while(currentActiveTransaction.isNull()) { + while(currentActiveTransaction.isNull() || currentActiveTransaction->getTransactionBody().isNull()) { Poco::Thread::sleep(10); currentActiveTransaction = mSession->getNextReadyTransaction(); } - if(!currentActiveTransaction->isTransfer()) { + if(!currentActiveTransaction->getTransactionBody()->isTransfer()) { addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); } else { auto signing = new SigningTransaction(currentActiveTransaction, new_user); diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index f99e2bd5f..a7bd6484b 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -47,6 +47,7 @@ bool SessionManager::init() case VALIDATE_EMAIL: mValidations[i] = new Poco::RegularExpression("^[a-zA-Z0-9.!#$%&�*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"); break; case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-_])[A-Za-z0-9@$!%*?&+-_]{8,}$"); break; case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break; + case VALIDATE_GROUP_ALIAS: mValidations[i] = new Poco::RegularExpression("^[a-z0-9-]{3,120}"); break; case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break; case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break; case VALIDATE_ONLY_DECIMAL: mValidations[i] = new Poco::RegularExpression("^[0-9]*(\.|,)[0-9]*$"); break; diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index 1463e6502..27e2a7021 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -27,6 +27,7 @@ enum SessionValidationTypes { VALIDATE_EMAIL, VALIDATE_PASSWORD, VALIDATE_PASSPHRASE, + VALIDATE_GROUP_ALIAS, VALIDATE_HAS_NUMBER, VALIDATE_ONLY_INTEGER, VALIDATE_ONLY_DECIMAL, diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index 8616282fd..b33d46d4b 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -139,7 +139,7 @@ namespace DataTypeConverter } - MemoryBin* base64ToBin(const std::string& base64String) + MemoryBin* base64ToBin(const std::string& base64String, int variant /*= sodium_base64_VARIANT_ORIGINAL*/) { /* int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, @@ -161,10 +161,18 @@ namespace DataTypeConverter mm->releaseMemory(bin); return nullptr; } + if (resultBinSize < binSize) { + auto bin_real = mm->getFreeMemory(resultBinSize); + memcpy(*bin_real, *bin, resultBinSize); + mm->releaseMemory(bin); + return bin_real; + } return bin; } + + std::string binToBase64(const unsigned char* data, size_t size, int variant /*= sodium_base64_VARIANT_ORIGINAL*/) { diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index ea16f31b7..c778f198a 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -29,7 +29,7 @@ namespace DataTypeConverter { NumberParseState strToDouble(const std::string& input, double& result); MemoryBin* hexToBin(const std::string& hexString); - MemoryBin* base64ToBin(const std::string& base64String); + MemoryBin* base64ToBin(const std::string& base64String, int variant = sodium_base64_VARIANT_ORIGINAL); std::string binToBase64(const unsigned char* data, size_t size, int variant = sodium_base64_VARIANT_ORIGINAL); diff --git a/src/cpp/model/gradido/GroupMemberUpdate.cpp b/src/cpp/model/gradido/GroupMemberUpdate.cpp new file mode 100644 index 000000000..cf0860082 --- /dev/null +++ b/src/cpp/model/gradido/GroupMemberUpdate.cpp @@ -0,0 +1,48 @@ +#include "GroupMemberUpdate.h" +#include "../../Crypto/KeyPairEd25519.h" +#include "../../controller/Group.h" +#include "../../SingletonManager/SessionManager.h" + +namespace model { + namespace gradido { + GroupMemberUpdate::GroupMemberUpdate(const std::string& memo, const proto::gradido::GroupMemberUpdate &protoGroupMemberUpdate) + : TransactionBase(memo), mProtoMemberUpdate(protoGroupMemberUpdate) + { + + } + + GroupMemberUpdate::~GroupMemberUpdate() + { + + } + + int GroupMemberUpdate::prepare() + { + const static char functionName[] = { "GroupMemberUpdate::prepare" }; + if (mProtoMemberUpdate.user_pubkey().size() != KeyPairEd25519::getPublicKeySize()) { + addError(new Error(functionName, "pubkey not set or wrong size")); + return -1; + } + + if (mProtoMemberUpdate.member_update_type() != proto::gradido::GroupMemberUpdate::ADD_USER) { + addError(new Error(functionName, "user move not implemented yet!")); + return 1; + } + auto target_group = mProtoMemberUpdate.target_group(); + auto sm = SessionManager::getInstance(); + if (sm->isValid(target_group, VALIDATE_GROUP_ALIAS)) { + auto groups = controller::Group::load(mProtoMemberUpdate.target_group()); + if (groups.size() != 1) { + addError(new ParamError(functionName, "target group not known or not unambiguous: ", target_group)); + return -2; + } + } + else { + addError(new Error(functionName, "target group isn't valid group alias string ")); + return -3; + } + + return 0; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/gradido/GroupMemberUpdate.h b/src/cpp/model/gradido/GroupMemberUpdate.h new file mode 100644 index 000000000..633e93462 --- /dev/null +++ b/src/cpp/model/gradido/GroupMemberUpdate.h @@ -0,0 +1,22 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_GROUP_MEMBER_UPDATE_H +#define __GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_GROUP_MEMBER_UPDATE_H + +#include "TransactionBase.h" +#include "../../proto/gradido/GroupMemberUpdate.pb.h" + +namespace model { + namespace gradido { + class GroupMemberUpdate : public TransactionBase + { + public: + GroupMemberUpdate(const std::string& memo, const proto::gradido::GroupMemberUpdate &protoGroupMemberUpdate); + ~GroupMemberUpdate(); + int prepare(); + + protected: + const proto::gradido::GroupMemberUpdate& mProtoMemberUpdate; + }; + } +} + +#endif \ No newline at end of file diff --git a/src/cpp/model/gradido/ManageNodeBody.cpp b/src/cpp/model/gradido/ManageNodeBody.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/gradido/ManageNodeBody.h b/src/cpp/model/gradido/ManageNodeBody.h new file mode 100644 index 000000000..8e757f935 --- /dev/null +++ b/src/cpp/model/gradido/ManageNodeBody.h @@ -0,0 +1,10 @@ +#ifndef __GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_MANAGE_NODE_BODY_H +#define __GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_MANAGE_NODE_BODY_H + +namespace model { + namespace gradido { + + } +} + +#endif //__GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_MANAGE_NODE_BODY_H \ No newline at end of file diff --git a/src/cpp/model/gradido/TransactionBase.h b/src/cpp/model/gradido/TransactionBase.h index f47420d54..1d7ade30d 100644 --- a/src/cpp/model/gradido/TransactionBase.h +++ b/src/cpp/model/gradido/TransactionBase.h @@ -21,6 +21,7 @@ namespace model { { public: TransactionBase(const std::string& memo); + //! \return 0 if ok, < 0 if error, > 0 if not implemented virtual int prepare() = 0; static std::string amountToString(google::protobuf::int64 amount); diff --git a/src/cpp/model/gradido/TransactionBody.cpp b/src/cpp/model/gradido/TransactionBody.cpp new file mode 100644 index 000000000..bfc6ad54a --- /dev/null +++ b/src/cpp/model/gradido/TransactionBody.cpp @@ -0,0 +1,114 @@ +#include "TransactionBody.h" + + +namespace model { + namespace gradido { + + TransactionBody::TransactionBody() + : mTransactionSpecific(nullptr), mType(TRANSACTION_NONE) + { + } + + TransactionBody::~TransactionBody() + { + lock(); + if (mTransactionSpecific) { + delete mTransactionSpecific; + mTransactionSpecific = nullptr; + } + unlock(); + } + + Poco::AutoPtr TransactionBody::create(const std::string& memo, Poco::AutoPtr user, proto::gradido::GroupMemberUpdate_MemberUpdateType type, const std::string& targetGroupAlias) + { + Poco::AutoPtr obj = new TransactionBody; + obj->mTransactionBody.set_memo(memo); + auto group_member_update = obj->mTransactionBody.mutable_group_member_update(); + + group_member_update->set_user_pubkey(user->getModel()->getPublicKey(), KeyPairEd25519::getPublicKeySize()); + group_member_update->set_member_update_type(type); + group_member_update->set_target_group(targetGroupAlias); + + obj->mType = TRANSACTION_GROUP_MEMBER_UPDATE; + obj->mTransactionSpecific = new GroupMemberUpdate(memo, obj->mTransactionBody.group_member_update()); + + return obj; + } + + Poco::AutoPtr TransactionBody::create(const MemoryBin* protoMessageBin) + { + Poco::AutoPtr obj = new TransactionBody; + + std::string binString((char*)protoMessageBin, protoMessageBin->size()); + + if (!obj->mTransactionBody.ParseFromString(binString)) { + return nullptr; + } + + // check Type + if (obj->mTransactionBody.has_creation()) { + obj->mType = TRANSACTION_CREATION; + obj->mTransactionSpecific = new model::gradido::TransactionCreation(obj->mTransactionBody.memo(), obj->mTransactionBody.creation()); + } + else if (obj->mTransactionBody.has_transfer()) { + obj->mType = TRANSACTION_TRANSFER; + obj->mTransactionSpecific = new model::gradido::TransactionTransfer(obj->mTransactionBody.memo(), obj->mTransactionBody.transfer()); + } + else if (obj->mTransactionBody.has_group_member_update()) { + obj->mType = TRANSACTION_GROUP_MEMBER_UPDATE; + obj->mTransactionSpecific = new model::gradido::GroupMemberUpdate(obj->mTransactionBody.memo(), obj->mTransactionBody.group_member_update()); + } + return obj; + } + + + std::string TransactionBody::getMemo() + { + Poco::ScopedLock _lock(mWorkMutex); + if (mTransactionBody.IsInitialized()) { + std::string result(mTransactionBody.memo()); + + return result; + } + return ""; + } + + std::string TransactionBody::getBodyBytes() + { + Poco::ScopedLock _lock(mWorkMutex); + if (mTransactionBody.IsInitialized()) { + auto size = mTransactionBody.ByteSize(); + //auto bodyBytesSize = MemoryManager::getInstance()->getFreeMemory(mProtoCreation.ByteSizeLong()); + std::string resultString(size, 0); + if (!mTransactionBody.SerializeToString(&resultString)) { + //addError(new Error("TransactionCreation::getBodyBytes", "error serializing string")); + throw new Poco::Exception("error serializing string"); + } + + return resultString; + } + + return ""; + } + + TransactionCreation* TransactionBody::getCreationTransaction() + { + return dynamic_cast(mTransactionSpecific); + } + + TransactionTransfer* TransactionBody::getTransferTransaction() + { + return dynamic_cast(mTransactionSpecific); + } + + GroupMemberUpdate* TransactionBody::getGroupMemberUpdate() + { + return dynamic_cast(mTransactionSpecific); + } + + TransactionBase* TransactionBody::getTransactionBase() + { + return mTransactionSpecific; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/gradido/TransactionBody.h b/src/cpp/model/gradido/TransactionBody.h new file mode 100644 index 000000000..f97fb4d6e --- /dev/null +++ b/src/cpp/model/gradido/TransactionBody.h @@ -0,0 +1,56 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_TRANSACTION_BASE_H +#define GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_TRANSACTION_BASE_H + +#include "../../controller/User.h" +#include "GroupMemberUpdate.h" +#include "TransactionCreation.h" +#include "TransactionTransfer.h" + +#include "../../proto/gradido/TransactionBody.pb.h" + +#include "../../lib/MultithreadContainer.h" + +namespace model { + namespace gradido { + + enum TransactionType { + TRANSACTION_NONE, + TRANSACTION_CREATION, + TRANSACTION_TRANSFER, + TRANSACTION_GROUP_MEMBER_UPDATE + }; + + + class TransactionBody : public Poco::RefCountedObject, UniLib::lib::MultithreadContainer + { + public: + ~TransactionBody(); + + static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr user, proto::gradido::GroupMemberUpdate_MemberUpdateType type, const std::string& targetGroupAlias); + static Poco::AutoPtr create(const MemoryBin* protoMessageBin); + + inline TransactionType getType() { lock(); auto t = mType; unlock(); return t; } + std::string getMemo(); + + + bool isCreation() { Poco::ScopedLock _lock(mWorkMutex); return mType == TRANSACTION_CREATION; } + bool isTransfer() { Poco::ScopedLock _lock(mWorkMutex); return mType == TRANSACTION_TRANSFER; } + bool isGroupMemberUpdate() { Poco::ScopedLock _lock(mWorkMutex); return mType == TRANSACTION_GROUP_MEMBER_UPDATE; } + + std::string getBodyBytes(); + + TransactionCreation* getCreationTransaction(); + TransactionTransfer* getTransferTransaction(); + GroupMemberUpdate* getGroupMemberUpdate(); + TransactionBase* getTransactionBase(); + + protected: + TransactionBody(); + proto::gradido::TransactionBody mTransactionBody; + TransactionBase* mTransactionSpecific; + TransactionType mType; + }; + } +} + +#endif //GRADIDO_LOGIN_SERVER_MODEL_GRADIDO_TRANSACTION_BASE_H \ No newline at end of file diff --git a/src/cpp/tasks/ProcessingTransaction.cpp b/src/cpp/tasks/ProcessingTransaction.cpp index 2112b4448..300a8efd6 100644 --- a/src/cpp/tasks/ProcessingTransaction.cpp +++ b/src/cpp/tasks/ProcessingTransaction.cpp @@ -3,6 +3,7 @@ #include "../model/gradido/TransactionCreation.h" #include "../model/gradido/TransactionTransfer.h" +#include "../model/gradido/GroupMemberUpdate.h" #include "../SingletonManager/SingletonTaskObserver.h" @@ -10,7 +11,7 @@ #include "../lib/JsonRequest.h" ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated/* = Poco::DateTime()*/) - : mType(TRANSACTION_NONE), mProtoMessageBase64(proto_message_base64), mTransactionSpecific(nullptr), mUserEmailHash(userEmailHash), + : mProtoMessageBase64(proto_message_base64), mUserEmailHash(userEmailHash), mLang(lang), mTransactionCreated(transactionCreated) { mHashMutex.lock(); @@ -26,10 +27,6 @@ ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_ba ProcessingTransaction::~ProcessingTransaction() { lock(); - if (mTransactionSpecific) { - delete mTransactionSpecific; - mTransactionSpecific = nullptr; - } auto observer = SingletonTaskObserver::getInstance(); if (mUserEmailHash != 0) { observer->removeTask(mUserEmailHash, TASK_OBSERVER_PREPARE_TRANSACTION); @@ -77,46 +74,33 @@ void ProcessingTransaction::reportErrorToCommunityServer(std::string error, std: int ProcessingTransaction::run() { lock(); - //mTransactionBody.ParseFromString(); - unsigned char* binBuffer = (unsigned char*)malloc(mProtoMessageBase64.size()); - size_t resultingBinSize = 0; - size_t base64_size = mProtoMessageBase64.size(); + + + auto mm = MemoryManager::getInstance(); + auto protoMessageBin = DataTypeConverter::base64ToBin(mProtoMessageBase64); + auto langM = LanguageManager::getInstance(); auto catalog = langM->getFreeCatalog(mLang); - if (sodium_base642bin( - binBuffer, base64_size, - mProtoMessageBase64.data(), base64_size, - nullptr, &resultingBinSize, nullptr, - sodium_base64_VARIANT_ORIGINAL)) + if (!protoMessageBin) { - free(binBuffer); addError(new Error("ProcessingTransaction", "error decoding base64")); reportErrorToCommunityServer(catalog->gettext("decoding error"), catalog->gettext("Error decoding base64 string"), "-1"); unlock(); return -1; } - std::string binString((char*)binBuffer, resultingBinSize); - free(binBuffer); - if (!mTransactionBody.ParseFromString(binString)) { + mTransactionBody = model::gradido::TransactionBody::create(protoMessageBin); + mm->releaseMemory(protoMessageBin); + if (mTransactionBody.isNull()) { addError(new Error("ProcessingTransaction", "error creating Transaction from binary Message")); reportErrorToCommunityServer(catalog->gettext("decoding error"), catalog->gettext("Error by parsing to protobuf message"), "-1"); unlock(); return -2; } - - // check Type - if (mTransactionBody.has_creation()) { - mType = TRANSACTION_CREATION; - mTransactionSpecific = new model::gradido::TransactionCreation(mTransactionBody.memo(), mTransactionBody.creation()); - } - else if (mTransactionBody.has_transfer()) { - mType = TRANSACTION_TRANSFER; - mTransactionSpecific = new model::gradido::TransactionTransfer(mTransactionBody.memo(), mTransactionBody.transfer()); - } - if (mTransactionSpecific) { - if (mTransactionSpecific->prepare()) { - getErrors(mTransactionSpecific); + auto transaction_specific = mTransactionBody->getTransactionBase(); + if (transaction_specific) { + if (transaction_specific->prepare()) { + getErrors(transaction_specific); addError(new Error("ProcessingTransaction", "error preparing")); reportErrorToCommunityServer(catalog->gettext("format error"), catalog->gettext("format of specific transaction not known, wrong proto version?"), Poco::DateTimeFormatter::format(mTransactionCreated, "%s")); unlock(); @@ -126,44 +110,3 @@ int ProcessingTransaction::run() unlock(); return 0; } - -std::string ProcessingTransaction::getMemo() -{ - lock(); - if (mTransactionBody.IsInitialized()) { - std::string result(mTransactionBody.memo()); - unlock(); - return result; - } - unlock(); - return ""; -} - -std::string ProcessingTransaction::getBodyBytes() -{ - lock(); - if (mTransactionBody.IsInitialized()) { - auto size = mTransactionBody.ByteSize(); - //auto bodyBytesSize = MemoryManager::getInstance()->getFreeMemory(mProtoCreation.ByteSizeLong()); - std::string resultString(size, 0); - if (!mTransactionBody.SerializeToString(&resultString)) { - addError(new Error("TransactionCreation::getBodyBytes", "error serializing string")); - unlock(); - return ""; - } - unlock(); - return resultString; - } - unlock(); - return ""; -} - -model::gradido::TransactionCreation* ProcessingTransaction::getCreationTransaction() -{ - return dynamic_cast(mTransactionSpecific); -} - -model::gradido::TransactionTransfer* ProcessingTransaction::getTransferTransaction() -{ - return dynamic_cast(mTransactionSpecific); -} \ No newline at end of file diff --git a/src/cpp/tasks/ProcessingTransaction.h b/src/cpp/tasks/ProcessingTransaction.h index 2864a1298..6566b838e 100644 --- a/src/cpp/tasks/ProcessingTransaction.h +++ b/src/cpp/tasks/ProcessingTransaction.h @@ -5,9 +5,7 @@ #include "../lib/NotificationList.h" #include "../lib/DRHash.h" -#include "../model/gradido/TransactionBase.h" - -#include "../proto/gradido/TransactionBody.pb.h" +#include "../model/gradido/TransactionBody.h" #include "../SingletonManager/LanguageManager.h" @@ -18,17 +16,12 @@ * @desc: Task for processing Transactions */ -enum TransactionType { - TRANSACTION_NONE, - TRANSACTION_CREATION, - TRANSACTION_TRANSFER -}; namespace model { namespace gradido { class TransactionCreation; class TransactionTransfer; - + class GroupMemberUpdate; } } class SigningTransaction; @@ -40,37 +33,29 @@ class ProcessingTransaction : public UniLib::controller::CPUTask, public Notific public: //! \param lang for error messages in user language ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated = Poco::DateTime()); + //ProcessingTransaction(const model::gradido::TransactionBody) virtual ~ProcessingTransaction(); int run(); const char* getResourceType() const { return "ProcessingTransaction"; }; - inline TransactionType getType() { lock(); auto t = mType; unlock(); return t; } - std::string getMemo(); - // not secured zone, no locking - bool isCreation() { return mType == TRANSACTION_CREATION; } - bool isTransfer() { return mType == TRANSACTION_TRANSFER; } - - model::gradido::TransactionCreation* getCreationTransaction(); - model::gradido::TransactionTransfer* getTransferTransaction(); - static HASH calculateHash(const std::string& proto_message_base64); static std::string calculateGenericHash(const std::string& protoMessageBase64); inline HASH getHash() { mHashMutex.lock(); HASH hs = mHash; mHashMutex.unlock(); return hs; } - std::string getBodyBytes(); + inline Poco::AutoPtr getTransactionBody() { return mTransactionBody; } + protected: void reportErrorToCommunityServer(std::string error, std::string errorDetails, std::string created); - TransactionType mType; + std::string mProtoMessageBase64; - - proto::gradido::TransactionBody mTransactionBody; - model::gradido::TransactionBase* mTransactionSpecific; + Poco::AutoPtr mTransactionBody; + HASH mHash; DHASH mUserEmailHash; diff --git a/src/cpp/tasks/SigningTransaction.cpp b/src/cpp/tasks/SigningTransaction.cpp index 11392e0bd..04dcbc40d 100644 --- a/src/cpp/tasks/SigningTransaction.cpp +++ b/src/cpp/tasks/SigningTransaction.cpp @@ -99,7 +99,10 @@ int SigningTransaction::run() { // get body bytes proto::gradido::GradidoTransaction transaction; auto bodyBytes = transaction.mutable_body_bytes(); - *bodyBytes = mProcessingeTransaction->getBodyBytes(); + auto transaction_body = mProcessingeTransaction->getTransactionBody(); + if (!transaction_body.isNull()) { + *bodyBytes = transaction_body->getBodyBytes(); + } if (*bodyBytes == "") { getErrors(mProcessingeTransaction); if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); diff --git a/src/cpsp/PassphrasedTransaction.cpsp b/src/cpsp/PassphrasedTransaction.cpsp index 8c360da79..ac772ceab 100644 --- a/src/cpsp/PassphrasedTransaction.cpsp +++ b/src/cpsp/PassphrasedTransaction.cpsp @@ -103,7 +103,8 @@ enum PageState { Poco::Thread::sleep(10); currentActiveTransaction = session->getNextReadyTransaction(); } - if(!currentActiveTransaction->isTransfer()) { + auto transaction_body = currentActiveTransaction->getTransactionBody(); + if(transaction_body.isNull() || !transaction_body->isTransfer()) { addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); } else { //auto signing = new SigningTransaction(currentActiveTransaction, user); diff --git a/src/cpsp/checkTransaction.cpsp b/src/cpsp/checkTransaction.cpsp index 439cc9fc1..e603e3664 100644 --- a/src/cpsp/checkTransaction.cpsp +++ b/src/cpsp/checkTransaction.cpsp @@ -108,15 +108,22 @@ enum PageState { } return; } - auto processingTransaction = mSession->getNextReadyTransaction(¬ReadyTransactions); + // skip transactions with errors + Poco::AutoPtr processingTransaction; + Poco::AutoPtr transaction_body; + do { + processingTransaction = mSession->getNextReadyTransaction(¬ReadyTransactions); + transaction_body = processingTransaction->getTransactionBody(); + } while(!processingTransaction.isNull() && transaction_body.isNull()); + if(sumTransactions > 0) { enableLogout = false; } - if(PAGE_NO_TRANSACTIONS == state && !processingTransaction.isNull()) { - auto transactionType = processingTransaction->getType(); + if(PAGE_NO_TRANSACTIONS == state && !processingTransaction.isNull() && !transaction_body.isNull()) { + auto transactionType = transaction_body->getType(); switch(transactionType) { - case TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; - case TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; + case model::gradido::TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; + case model::gradido::TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; } } @@ -159,7 +166,7 @@ enum PageState {

<%= gettext("Transaktion Unterzeichnen") %>

<% if(state == PAGE_TRANSACTION_TRANSFER) { - auto transferTransaction = processingTransaction->getTransferTransaction(); + auto transferTransaction = transaction_body->getTransferTransaction(); memo = transferTransaction->getMemo(); %>

<%= gettext("Überweisung") %>

@@ -180,7 +187,7 @@ enum PageState { <% } %>
<% } else if(PAGE_TRANSACTION_CREATION == state) { - auto creationTransaction = processingTransaction->getCreationTransaction(); + auto creationTransaction = transaction_body->getCreationTransaction(); auto transactionUser = creationTransaction->getUser(); memo = creationTransaction->getMemo(); %> diff --git a/src/cpsp/repairDefectPassphrase.cpsp b/src/cpsp/repairDefectPassphrase.cpsp index 960466cd5..c90743ae0 100644 --- a/src/cpsp/repairDefectPassphrase.cpsp +++ b/src/cpsp/repairDefectPassphrase.cpsp @@ -139,11 +139,11 @@ enum PageState } else if(stateString == "success") { printf("[repairDefectPassphrase] request success, wait on transaction ready\n"); auto currentActiveTransaction = mSession->getNextReadyTransaction(); - while(currentActiveTransaction.isNull()) { + while(currentActiveTransaction.isNull() || currentActiveTransaction->getTransactionBody().isNull()) { Poco::Thread::sleep(10); currentActiveTransaction = mSession->getNextReadyTransaction(); } - if(!currentActiveTransaction->isTransfer()) { + if(!currentActiveTransaction->getTransactionBody()->isTransfer()) { addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); } else { auto signing = new SigningTransaction(currentActiveTransaction, new_user);