From c4b591d0d8ead542a5d269f4b85654395e756fd4 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 2 Nov 2020 16:53:20 +0100 Subject: [PATCH] get pending task, add to group, create and transfer transaction together with community server working --- .../HTTPInterface/CheckTransactionPage.cpp | 328 +++++++++++------- .../JSONInterface/JsonCreateTransaction.cpp | 112 +++++- src/cpp/JSONInterface/JsonCreateTransaction.h | 1 + src/cpp/JSONInterface/JsonGetLogin.cpp | 12 +- src/cpp/JSONInterface/JsonNetworkInfos.cpp | 68 ++++ src/cpp/JSONInterface/JsonNetworkInfos.h | 16 + src/cpp/JSONInterface/JsonNetwortkInfos.h | 0 .../JsonRequestHandlerFactory.cpp | 4 + .../SingletonManager/PendingTasksManager.cpp | 37 ++ .../SingletonManager/PendingTasksManager.h | 2 + src/cpp/SingletonManager/SessionManager.cpp | 2 +- src/cpp/model/gradido/Transaction.cpp | 17 +- src/cpp/model/gradido/Transaction.h | 8 +- src/cpp/model/gradido/TransactionBody.cpp | 4 +- src/cpp/model/gradido/TransactionBody.h | 2 +- src/cpp/model/gradido/TransactionTransfer.cpp | 16 +- src/cpp/model/table/PendingTask.cpp | 5 +- src/cpp/model/table/PendingTask.h | 1 + src/cpp/model/table/User.cpp | 6 + src/cpsp/checkTransaction.cpsp | 148 ++++++-- 20 files changed, 603 insertions(+), 186 deletions(-) create mode 100644 src/cpp/JSONInterface/JsonNetworkInfos.h delete mode 100644 src/cpp/JSONInterface/JsonNetwortkInfos.h diff --git a/src/cpp/HTTPInterface/CheckTransactionPage.cpp b/src/cpp/HTTPInterface/CheckTransactionPage.cpp index 43d4f2efc..00a242545 100644 --- a/src/cpp/HTTPInterface/CheckTransactionPage.cpp +++ b/src/cpp/HTTPInterface/CheckTransactionPage.cpp @@ -53,6 +53,8 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, std::string memo = ""; bool hasErrors = false; bool enableLogout = true; + int skip_count = 0; + int pending_task_id = 0; PageState state = PAGE_NO_TRANSACTIONS; @@ -64,10 +66,12 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, bool transaction_finalize_run = false; bool transaction_finalize_result = false; auto transactions_to_sign = pt->getTransactionsUserMustSign(account_user); + + //Poco::AutoPtr pending_task; model::gradido::Transaction* transaction = nullptr; Poco::AutoPtr transaction_body; - if(transactions_to_sign.size() > 0) + if(!form.empty()) { transaction = dynamic_cast(transactions_to_sign[0].get()); transaction_body = transaction->getTransactionBody(); @@ -147,18 +151,28 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, } } if(abort != "") + /* + auto ok = form.get("ok", ""); + auto abort = form.get("abort", ""); + auto skip = form.get("skip", ""); + auto skip_count_str = form.get("skip-count", "0"); + auto pending_task_id_string = form.get("pending-task-id", ""); + DataTypeConverter::strToInt(skip_count_str, skip_count); + + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(pending_task_id_string, pending_task_id)) + { + // load transaction from pending task manager + pending_task = pt->getPendingTask(pending_task_id); + if(!pending_task.isNull() && pending_task->getModel()->isGradidoTransaction()) + */ { - // make sure we have the correct transaction - transaction = nullptr; - transaction_body.assign(nullptr); - for(auto it = transactions_to_sign.begin(); it != transactions_to_sign.end(); it++) - { - if((*it)->getModel()->getID() == pending_task_id) { - transaction = dynamic_cast(it->get()); - transaction_body = transaction->getTransactionBody(); - break; - } + transaction = dynamic_cast(pending_task.get()); + if(transaction->hasSigned(account_user)) { + transaction = nullptr; + } else { + transaction_body = transaction->getTransactionBody(); } + if(abort != "") { //mSession->finalizeTransaction(false, true); @@ -166,8 +180,6 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, if(transaction && transaction->getModel()->getUserId() == user_model->getID()) { transaction->deleteFromDB(); - transaction_body.assign(nullptr); - transactions_to_sign.clear(); transaction = nullptr; } } @@ -195,29 +207,55 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, } if(!hasErrors) { //mSession->finalizeTransaction(true, false); - if(transaction->sign(account_user)) { - transaction_body.assign(nullptr); - transactions_to_sign.clear(); + if(transaction && transaction->sign(account_user)) { transaction = nullptr; } } } + else if(skip != "") + { + skip_count++; + transaction = nullptr; + } } else { - addError(new Error(gettext("Form Error"), gettext("error with field"))); + addError(new Error(gettext("Input Error"), gettext("Task no found"))); } + } else { + addError(new Error(gettext("Form Error"), gettext("error with field"))); } } + auto transactions_user_must_sign = pt->getTransactionsUserMustSign(account_user); + std::vector> transactions_someone_must_sign; + // TODO: work with community server roles + if(user_model->getRole() == model::table::ROLE_ADMIN) { + transactions_someone_must_sign = pt->getTransactionSomeoneMustSign(account_user); + } + std::vector> transactions_to_sign; + bool transaction_removeable = false; + int transaction_to_sign_index = 0; if(!transaction) { - transactions_to_sign = pt->getTransactionsUserMustSign(account_user); - if(transactions_to_sign.size() > 0) + if(transactions_user_must_sign.size() > skip_count) { + transactions_to_sign = transactions_user_must_sign; + transaction_to_sign_index = skip_count; + } else if(transactions_someone_must_sign.size() > (skip_count - transactions_user_must_sign.size())) { + transactions_to_sign = transactions_someone_must_sign; + transaction_to_sign_index = skip_count - transactions_user_must_sign.size(); + } + + if(transactions_to_sign.size() > transaction_to_sign_index) { - transaction = dynamic_cast(transactions_to_sign[0].get()); + transaction = dynamic_cast(transactions_to_sign[transaction_to_sign_index].get()); transaction_body = transaction->getTransactionBody(); + // user can only delete there own transactions + // TODO: Auto timeout for community transactions + if(transaction->getModel()->getUserId() == user_model->getID()) { + transaction_removeable = true; + } } } - size_t sumTransactions = transactions_to_sign.size(); + size_t sumTransactions = transactions_user_must_sign.size() + transactions_someone_must_sign.size(); if(sumTransactions == 0) { auto lastExternReferer = mSession->getLastReferer(); @@ -234,14 +272,14 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, return; } - if(sumTransactions > 0) + if(transactions_user_must_sign.size() > 0) { enableLogout = false; } - if(PAGE_NO_TRANSACTIONS == state && sumTransactions > 0) + if(PAGE_NO_TRANSACTIONS == state && transaction && !transaction_body.isNull()) { auto transactionType = transaction_body->getType(); - auto memo = transaction_body->getMemo(); + memo = transaction_body->getMemo(); switch(transactionType) { case model::gradido::TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; case model::gradido::TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; @@ -456,120 +494,120 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "
\n"; responseStream << "\t
\n"; responseStream << "\t\t

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

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

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

\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t\t"; -#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Konto") ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Gradido") ); responseStream << "\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t "; -#line 189 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" for(int i = 0; i < transferTransaction->getKontoTableSize(); i++) { responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 190 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if((i+1) % 2 == 0) { responseStream << "\n"; responseStream << "\t\t\t\t\t\t
\n"; responseStream << "\t\t\t\t\t"; -#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t\t
\n"; responseStream << "\t\t\t\t\t"; -#line 194 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t\t"; -#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 222 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( transferTransaction->getKontoNameCell(i) ); responseStream << "\n"; responseStream << "\t\t\t\t\t\t"; -#line 196 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( transferTransaction->getAmountCell(i) ); responseStream << "\n"; responseStream << "\t\t\t\t\t
\n"; responseStream << "\t\t\t "; -#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t "; -#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_TRANSACTION_CREATION == state) { auto creationTransaction = transaction_body->getCreationTransaction(); auto transactionUser = creationTransaction->getUser(); responseStream << "\n"; responseStream << "\t\t\t\t

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

\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t"; -#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Konto") ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 208 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 235 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Zieldatum") ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 209 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 236 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Gradido") ); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t"; -#line 212 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 239 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!transactionUser.isNull()) { auto user_model = transactionUser->getModel(); responseStream << "\n"; responseStream << "\t\t\t\t\t\t"; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getFirstName() ); responseStream << " "; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getLastName() ); responseStream << " <"; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getEmail() ); responseStream << ">\n"; responseStream << "\t\t\t\t\t"; -#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 243 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t\t0x"; -#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( creationTransaction->getPublicHex() ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 218 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( creationTransaction->getTargetDateString() ); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 220 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( creationTransaction->getAmountString() ); responseStream << " GDD\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t "; -#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 250 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_TRANSACTION_GROUP_ADD_MEMBER == state) { auto groupMemberUpdateTransaction = transaction_body->getGroupMemberUpdate(); auto groups = controller::Group::load(groupMemberUpdateTransaction->getTargetGroupAlias()); @@ -584,160 +622,186 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, } responseStream << "\n"; responseStream << "\t\t\t

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

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

"; -#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!user.isNull()) { responseStream << "\n"; responseStream << "\t\t\t\t\tBenutzer: "; -#line 239 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 266 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user->getEmailWithNames() ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 240 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\tAccount public key: "; -#line 241 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( groupMemberUpdateTransaction->getPublicKeyHex() ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "

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

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

\n"; responseStream << "\t\t\t\t\t
    \n"; responseStream << "\t\t\t\t\t\t
  • "; -#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Name") ); responseStream << ": "; -#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getName() ); responseStream << "
  • \n"; responseStream << "\t\t\t\t\t\t
  • "; -#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Alias") ); responseStream << ": "; -#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getAlias() ); responseStream << "
  • \n"; responseStream << "\t\t\t\t\t\t
  • "; -#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 275 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Url") ); responseStream << ": getUrl() ); responseStream << "/pages/visitor\" target=\"_blank\">"; -#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 275 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getUrl() ); responseStream << "
  • \n"; responseStream << "\t\t\t\t\t\t
  • "; -#line 249 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 276 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( group_model->getDescription() ); responseStream << "
  • \n"; responseStream << "\t\t\t\t\t
\n"; responseStream << "\t\t\t\t"; -#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 278 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else { responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 279 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Unbekannte Gruppe") ); responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 253 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t"; -#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext("Es haben bereits ") ); -#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( std::to_string(transaction->getSignCount()) ); -#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( gettext(" unterzeichnet") ); responseStream << "\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t \n"; responseStream << "\t\t\t "; -#line 257 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 284 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } else if(PAGE_USER_DATA_CORRUPTED == state) { responseStream << "\n"; responseStream << "\t\t\t\t

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

\n"; responseStream << "\t\t\t "; -#line 259 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\tAktives Konto\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t"; -#line 265 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + responseStream << "\t\t\t "; +#line 287 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + if(PAGE_NO_TRANSACTIONS == state) { responseStream << "\n"; + responseStream << "\t\t\t\t"; +#line 288 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + responseStream << ( gettext("Zurück") ); + responseStream << "\n"; + responseStream << "\t\t\t "; +#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + } else { responseStream << "\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tAktives Konto\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t"; +#line 295 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( user_model->getNameWithEmailHtml() ); responseStream << "\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\tVerwendungszweck\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t"; -#line 273 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tVerwendungszweck\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t"; +#line 303 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" responseStream << ( memo ); responseStream << "\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\t\n"; + responseStream << "\t\t\t\t\t"; +#line 307 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + if(transaction) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tgetModel()->getID() ); responseStream << "\">\n"; - responseStream << "\t\t\t\t"; -#line 278 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + responseStream << "\t\t\t\t\t"; +#line 309 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 311 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(!account_user->hasPassword()) { responseStream << "\n"; - responseStream << "\t\t\t\t
\n"; - responseStream << "\t\t\t\t\t
\n"; + responseStream << "\t\t\t\t\t"; +#line 316 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" } responseStream << "\n"; - responseStream << "\t\t\t\t"; -#line 284 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + responseStream << "\t\t\t\t\t"; +#line 317 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" if(PAGE_USER_DATA_CORRUPTED != state && user_model->isEmailChecked()) { responseStream << "\n"; - responseStream << "\t\t\t\t\t\n"; - responseStream << "\t\t\t\t"; -#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\t"; -#line 292 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" +#line 322 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t"; +#line 323 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + if(transaction_removeable) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\n"; @@ -750,8 +814,26 @@ void CheckTransactionPage::handleRequest(Poco::Net::HTTPServerRequest& request, responseStream << "\t\t\t\t\t\t\n"; responseStream << "\t\t\t\t"; #line 245 "F:\\Gradido\\gradido_login_server_production\\src\\cpsp\\checkTransaction.cpsp" - } responseStream << "\n"; + responseStream << "\n"; responseStream << "\t\t\t\n"; + responseStream << "\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 328 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + } else { responseStream << "\n"; + responseStream << "\t\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 333 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t"; +#line 335 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkTransaction.cpsp" + } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; responseStream << "
\n"; diff --git a/src/cpp/JSONInterface/JsonCreateTransaction.cpp b/src/cpp/JSONInterface/JsonCreateTransaction.cpp index 229e2540a..ef4bb34e6 100644 --- a/src/cpp/JSONInterface/JsonCreateTransaction.cpp +++ b/src/cpp/JSONInterface/JsonCreateTransaction.cpp @@ -6,6 +6,8 @@ #include "../model/gradido/Transaction.h" +#include "../SingletonManager/ErrorManager.h" + Poco::JSON::Object* JsonCreateTransaction::handle(Poco::Dynamic::Var params) { auto sm = SessionManager::getInstance(); @@ -40,12 +42,16 @@ Poco::JSON::Object* JsonCreateTransaction::handle(Poco::Dynamic::Var params) mSession = sm->getSession(session_id); if (!mSession) { - return customStateError("not found", "session not found"); + return stateError("session not found"); } auto user = mSession->getNewUser(); if (user.isNull()) { + auto em = ErrorManager::getInstance(); + em->addError(new Error(__FUNCDNAME__, "session hasn't a user, check code")); + em->sendErrorsAsEmail(); return customStateError("code error", "user is zero"); } + getTargetGroup(params); if (transaction_type == "transfer") { return transfer(params); @@ -64,43 +70,114 @@ Poco::JSON::Object* JsonCreateTransaction::handle(Poco::Dynamic::Var params) Poco::JSON::Object* JsonCreateTransaction::transfer(Poco::Dynamic::Var params) { auto target_pubkey = getTargetPubkey(params); + if (!target_pubkey) { + return customStateError("not found", "receiver not found"); + } + + auto user = mSession->getNewUser(); Poco::UInt32 amount = 0; + auto mm = MemoryManager::getInstance(); + Poco::JSON::Object* result = nullptr; + if (params.type() == typeid(Poco::JSON::Object::Ptr)) { Poco::JSON::Object::Ptr paramJsonObject = params.extract(); try { paramJsonObject->get("amount").convert(amount); } catch (Poco::Exception& ex) { - return stateError("json exception", ex.displayText()); + result = stateError("json exception", ex.displayText()); } } else { - return stateError("parameter format unknown"); + result = stateError("parameter format unknown"); } - - model::gradido::Transaction::createTransfer(mSession->getNewUser(), target_pubkey, mTargetGroup, amount, mMemo); - return stateSuccess(); + if (result) { + mm->releaseMemory(target_pubkey); + return result; + } + + if (!mReceiverUser.isNull() && mReceiverUser->getModel()) { + auto receiver_user_model = mReceiverUser->getModel(); + if (receiver_user_model->isDisabled()) { + result = customStateError("disabled", "receiver is disabled"); + } + if (!mTargetGroup.isNull() && receiver_user_model->getGroupId() != mTargetGroup->getModel()->getID()) { + result = stateError("user not in group", "receiver user isn't in target group"); + } + } + if (!result) { + model::gradido::Transaction::createTransfer(mSession->getNewUser(), target_pubkey, mTargetGroup, amount, mMemo); + result = stateSuccess(); + } + mm->releaseMemory(target_pubkey); + return result; } Poco::JSON::Object* JsonCreateTransaction::creation(Poco::Dynamic::Var params) { auto target_pubkey = getTargetPubkey(params); + if (!target_pubkey) { + return customStateError("not found", "receiver not found"); + } + Poco::UInt32 amount = 0; Poco::DateTime target_date; - if (params.type() == typeid(Poco::JSON::Object::Ptr)) { + auto mm = MemoryManager::getInstance(); + Poco::JSON::Object* result = nullptr; + + if (params.type() == typeid(Poco::JSON::Object::Ptr)) + { Poco::JSON::Object::Ptr paramJsonObject = params.extract(); try { paramJsonObject->get("amount").convert(amount); paramJsonObject->get("target_date").convert(target_date); } catch (Poco::Exception& ex) { - return stateError("json exception", ex.displayText()); + result = stateError("json exception", ex.displayText()); } } - else { - return stateError("parameter format unknown"); + else + { + result = stateError("parameter format unknown"); } - model::gradido::Transaction::createCreation(mSession->getNewUser(), amount, target_date, mMemo); - return stateSuccess(); + + if (amount <= 0 || amount > 10000000) { + result = customStateError("invalid parameter", "invalid amount", "GDD amount in GDD cent ]0,10000000]"); + } + + if (mReceiverUser.isNull()) { + mReceiverUser = controller::User::create(); + if (1 != mReceiverUser->load(*target_pubkey)) { + mReceiverUser.assign(nullptr); + result = customStateError("not found", "receiver not found"); + } + } + + if (result) { + mm->releaseMemory(target_pubkey); + return result; + } + + if (!mReceiverUser.isNull() && mReceiverUser->getModel()) { + auto receiver_user_model = mReceiverUser->getModel(); + + if (receiver_user_model->isDisabled()) { + result = customStateError("disabled", "receiver is disabled"); + } + if (!receiver_user_model->getGroupId()) { + result = stateError("receiver user hasn't group"); + } + if (receiver_user_model->getGroupId() != mSession->getNewUser()->getModel()->getGroupId()) { + result = stateError("user not in group", "target user is in another group"); + } + } + + if(!result) { + model::gradido::Transaction::createCreation(mReceiverUser, amount, target_date, mMemo); + result = stateSuccess(); + } + mm->releaseMemory(target_pubkey); + + return result; } Poco::JSON::Object* JsonCreateTransaction::groupMemberUpdate(Poco::Dynamic::Var params) @@ -139,12 +216,12 @@ MemoryBin* JsonCreateTransaction::getTargetPubkey(Poco::Dynamic::Var params) catch (Poco::Exception& ex) { return nullptr; } - auto user = controller::User::create(); + mReceiverUser = controller::User::create(); int result_count = 0; MemoryBin* result = nullptr; if (email != "") { - result_count = user->load(email); + result_count = mReceiverUser->load(email); } else if (target_username != "") { int group_id = 0; @@ -153,13 +230,16 @@ MemoryBin* JsonCreateTransaction::getTargetPubkey(Poco::Dynamic::Var params) } else { mSession->getNewUser()->getModel()->getGroupId(); } - result_count = user->getModel()->loadFromDB({ "username", "group_id" }, target_username, group_id, model::table::MYSQL_CONDITION_AND); + result_count = mReceiverUser->getModel()->loadFromDB({ "username", "group_id" }, target_username, group_id, model::table::MYSQL_CONDITION_AND); } else if (target_pubkey_hex != "") { result = DataTypeConverter::hexToBin(target_pubkey_hex); } if (1 == result_count) { - result = user->getModel()->getPublicKeyCopy(); + result = mReceiverUser->getModel()->getPublicKeyCopy(); + } + else { + mReceiverUser.assign(nullptr); } return result; } diff --git a/src/cpp/JSONInterface/JsonCreateTransaction.h b/src/cpp/JSONInterface/JsonCreateTransaction.h index 828ee8aa0..356e13fc1 100644 --- a/src/cpp/JSONInterface/JsonCreateTransaction.h +++ b/src/cpp/JSONInterface/JsonCreateTransaction.h @@ -21,6 +21,7 @@ protected: Session* mSession; std::string mMemo; Poco::AutoPtr mTargetGroup; + Poco::AutoPtr mReceiverUser; }; #endif // __JSON_INTERFACE_JSON_CREATE_TRANSACTION_ \ No newline at end of file diff --git a/src/cpp/JSONInterface/JsonGetLogin.cpp b/src/cpp/JSONInterface/JsonGetLogin.cpp index a881ae8a0..cf97302c2 100644 --- a/src/cpp/JSONInterface/JsonGetLogin.cpp +++ b/src/cpp/JSONInterface/JsonGetLogin.cpp @@ -4,6 +4,7 @@ #include "../SingletonManager/SessionManager.h" #include "../SingletonManager/SingletonTaskObserver.h" #include "../SingletonManager/ErrorManager.h" +#include "../SingletonManager/PendingTasksManager.h" #include "../lib/DataTypeConverter.h" @@ -12,6 +13,7 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params) int session_id = 0; auto sm = SessionManager::getInstance(); + auto pt = PendingTasksManager::getInstance(); auto observer = SingletonTaskObserver::getInstance(); if (params.isStruct()) { @@ -71,7 +73,15 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params) em->addError(new Error("JsonGetLogin::handle", "generic exception calling userModel->getJson: ")); em->sendErrorsAsEmail(); } - result->set("Transaction.pending", session->getProcessingTransactionCount()); + int pending = 0; + auto user_must_sign = pt->getTransactionsUserMustSign(userNew); + pending = user_must_sign.size(); + result->set("Transaction.pending", pending); + + auto some_must_sign = pt->getTransactionSomeoneMustSign(userNew); + //pending = some_must_sign.size(); + result->set("Transaction.can_signed", some_must_sign.size()); + auto executing = observer->getTaskCount(userModel->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION); if (executing < 0) { executing = 0; diff --git a/src/cpp/JSONInterface/JsonNetworkInfos.cpp b/src/cpp/JSONInterface/JsonNetworkInfos.cpp index e69de29bb..58a86db4e 100644 --- a/src/cpp/JSONInterface/JsonNetworkInfos.cpp +++ b/src/cpp/JSONInterface/JsonNetworkInfos.cpp @@ -0,0 +1,68 @@ +#include "JsonNetworkInfos.h" + +#include "../controller/Group.h" + +Poco::JSON::Object* JsonNetworkInfos::handle(Poco::Dynamic::Var params) +{ + /* + 'ask' => ['groups'] + */ + // incoming + + Poco::JSON::Array::Ptr askArray; + + // if is json object + if (params.type() == typeid(Poco::JSON::Object::Ptr)) { + Poco::JSON::Object::Ptr paramJsonObject = params.extract(); + /// Throws a RangeException if the value does not fit + /// into the result variable. + /// Throws a NotImplementedException if conversion is + /// not available for the given type. + /// Throws InvalidAccessException if Var is empty. + try { + askArray = paramJsonObject->getArray("ask"); + } + catch (Poco::Exception& ex) { + return stateError("json exception", ex.displayText()); + } + } + else { + return stateError("parameter format unknown"); + } + + + if (askArray.isNull()) { + return stateError("ask is zero or not an array"); + } + + + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "success"); + Poco::JSON::Array jsonErrorsArray; + Poco::JSON::Object json_network_infos; + + for (auto it = askArray->begin(); it != askArray->end(); it++) { + auto parameter = *it; + std::string parameterString; + try { + parameter.convert(parameterString); + if (parameterString == "groups") { + auto groups = controller::Group::listAll(); + Poco::JSON::Array json_groups; + for (auto it = groups.begin(); it != groups.end(); it++) { + auto group_model = (*it)->getModel(); + json_groups.add(group_model->getAlias()); + } + json_network_infos.set("groups", json_groups); + } + + } + catch (Poco::Exception& ex) { + jsonErrorsArray.add("ask parameter invalid"); + } + } + result->set("errors", jsonErrorsArray); + result->set("data", json_network_infos); + return result; + +} \ No newline at end of file diff --git a/src/cpp/JSONInterface/JsonNetworkInfos.h b/src/cpp/JSONInterface/JsonNetworkInfos.h new file mode 100644 index 000000000..fc6f20c10 --- /dev/null +++ b/src/cpp/JSONInterface/JsonNetworkInfos.h @@ -0,0 +1,16 @@ +#ifndef __JSON_INTERFACE_JSON_NETWORK_INFOS_ +#define __JSON_INTERFACE_JSON_NETWORK_INFOS_ + +#include "JsonRequestHandler.h" + +class JsonNetworkInfos : public JsonRequestHandler +{ +public: + Poco::JSON::Object* handle(Poco::Dynamic::Var params); + +protected: + + +}; + +#endif // __JSON_INTERFACE_JSON_GET_USERS_ \ No newline at end of file diff --git a/src/cpp/JSONInterface/JsonNetwortkInfos.h b/src/cpp/JSONInterface/JsonNetwortkInfos.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp b/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp index d0da6b67f..ea4670eca 100644 --- a/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandlerFactory.cpp @@ -12,6 +12,7 @@ #include "JsonTransaction.h" #include "JsonGetRunningUserTasks.h" #include "JsonGetUsers.h" +#include "JsonNetworkInfos.h" #include "JsonGetUserInfos.h" #include "JsonUpdateUserInfos.h" #include "JsonUnsecureLogin.h" @@ -57,6 +58,9 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c else if (url_first_part == "/getUsers") { return new JsonGetUsers; } + else if (url_first_part == "/networkInfos") { + return new JsonNetworkInfos; + } else if (url_first_part == "/createUser") { return new JsonCreateUser(client_host); } diff --git a/src/cpp/SingletonManager/PendingTasksManager.cpp b/src/cpp/SingletonManager/PendingTasksManager.cpp index 514e0a3df..35c28c72b 100644 --- a/src/cpp/SingletonManager/PendingTasksManager.cpp +++ b/src/cpp/SingletonManager/PendingTasksManager.cpp @@ -147,6 +147,42 @@ std::vector> PendingTasksManager::getTra return transactions_to_sign; } +std::vector> PendingTasksManager::getTransactionSomeoneMustSign(Poco::AutoPtr user) +{ + // TODO: don't use cast here, because can lead to errors + Poco::ScopedLock _lock(mWorkMutex); + std::vector> transactions_to_sign; + + for (auto map_it = mPendingTasks.begin(); map_it != mPendingTasks.end(); map_it++) + { + auto list = map_it->second; + for (auto list_it = list->begin(); list_it != list->end(); list_it++) + { + auto transaction = dynamic_cast(list_it->get()); + if (transaction->needSomeoneToSign(user)) { + transactions_to_sign.push_back(*list_it); + } + } + } + return transactions_to_sign; +} + +Poco::AutoPtr PendingTasksManager::getPendingTask(int pendingTaskId) +{ + Poco::ScopedLock _lock(mWorkMutex); + for (auto map_it = mPendingTasks.begin(); map_it != mPendingTasks.end(); map_it++) + { + auto list = map_it->second; + for (auto list_it = list->begin(); list_it != list->end(); list_it++) + { + if ((*list_it)->getModel()->getID() == pendingTaskId) { + return *list_it; + } + } + } + return nullptr; +} + void PendingTasksManager::reportErrorToCommunityServer(Poco::AutoPtr task, std::string error, std::string errorDetails) { // TODO: choose user specific server @@ -159,6 +195,7 @@ void PendingTasksManager::reportErrorToCommunityServer(Poco::AutoPtrgetCreated()); payload.set("id", task_model->getID()); + payload.set("type", task_model->getTaskTypeString()); payload.set("public_key", user_model->getPublicKeyHex()); payload.set("error", error); payload.set("errorMessage", errorDetails); diff --git a/src/cpp/SingletonManager/PendingTasksManager.h b/src/cpp/SingletonManager/PendingTasksManager.h index f60aec034..cec9bc5b6 100644 --- a/src/cpp/SingletonManager/PendingTasksManager.h +++ b/src/cpp/SingletonManager/PendingTasksManager.h @@ -40,7 +40,9 @@ public: const PendingTaskList* getTaskListForUser(int userId) const; bool hasPendingTask(Poco::AutoPtr user, model::table::TaskType type); std::vector> getPendingTasks(Poco::AutoPtr user, model::table::TaskType type); + Poco::AutoPtr getPendingTask(int pendingTaskId); std::vector> getTransactionsUserMustSign(Poco::AutoPtr user); + std::vector> getTransactionSomeoneMustSign(Poco::AutoPtr user); void reportErrorToCommunityServer(Poco::AutoPtr task, std::string error, std::string errorDetails); diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index a7bd6484b..0773e27fc 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -363,7 +363,7 @@ Session* SessionManager::getSession(int handle) //mWorkingMutex.lock(); auto it = mRequestSessionMap.find(handle); if (it != mRequestSessionMap.end()) { - printf("[SessionManager::getSession] found existing session, try if active...\n"); + //printf("[SessionManager::getSession] found existing session, try if active...\n"); result = it->second; int iResult = result->isActive(); if (iResult == -1) { diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index f620c3a48..44b1ae708 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -98,7 +98,7 @@ namespace model { return result; } - std::vector> Transaction::createTransfer(Poco::AutoPtr sender, MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo) + std::vector> Transaction::createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo) { std::vector> results; auto em = ErrorManager::getInstance(); @@ -385,6 +385,21 @@ namespace model { return !transaction_base->isPublicKeyForbidden(user->getModel()->getPublicKey()); } + bool Transaction::needSomeoneToSign(Poco::AutoPtr user) + { + if (!canSign(user)) return false; + Poco::ScopedLock _lock(mWorkMutex); + auto transaction_base = mTransactionBody->getTransactionBase(); + if (transaction_base->isPublicKeyRequired(user->getModel()->getPublicKey())) { + return false; + } + if (transaction_base->getMinSignatureCount() > getSignCount()) { + return true; + } + return false; + + } + int Transaction::runSendTransaction() { Poco::ScopedLock _lock(mWorkMutex); diff --git a/src/cpp/model/gradido/Transaction.h b/src/cpp/model/gradido/Transaction.h index 027eada45..e7d58db94 100644 --- a/src/cpp/model/gradido/Transaction.h +++ b/src/cpp/model/gradido/Transaction.h @@ -30,7 +30,7 @@ namespace model { static Poco::AutoPtr createGroupMemberUpdate(Poco::AutoPtr user, Poco::AutoPtr group); //! \brief transfer //! \return for cross group transaction return two transactions - static std::vector> createTransfer(Poco::AutoPtr sender, MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo); + static std::vector> createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo); //! \brief creation transaction static Poco::AutoPtr createCreation(Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate, const std::string& memo); static Poco::AutoPtr load(model::table::PendingTask* dbModel); @@ -48,13 +48,15 @@ namespace model { bool updateRequestInDB(); bool insertPendingTaskIntoDB(Poco::AutoPtr user, model::table::TaskType type); - //! return true if user must sign it and hasn't yet + //! \return true if user must sign it and hasn't yet bool mustSign(Poco::AutoPtr user); //! return true if user can sign transaction and hasn't yet bool canSign(Poco::AutoPtr user); - //! return true if user has already signed transaction + //! \return true if user has already signed transaction bool hasSigned(Poco::AutoPtr user); + //! \return true if at least one sign is missing and user isn't forbidden and isn't required + bool needSomeoneToSign(Poco::AutoPtr user); protected: Poco::AutoPtr mTransactionBody; diff --git a/src/cpp/model/gradido/TransactionBody.cpp b/src/cpp/model/gradido/TransactionBody.cpp index 95a7527eb..07443809d 100644 --- a/src/cpp/model/gradido/TransactionBody.cpp +++ b/src/cpp/model/gradido/TransactionBody.cpp @@ -36,7 +36,7 @@ namespace model { return obj; } - Poco::AutoPtr TransactionBody::create(const std::string& memo, Poco::AutoPtr sender, MemoryBin* receiverPublicKey, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId, Poco::AutoPtr group/* = nullptr*/) + Poco::AutoPtr TransactionBody::create(const std::string& memo, Poco::AutoPtr sender, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId, Poco::AutoPtr group/* = nullptr*/) { if (sender.isNull() || !sender->getModel()) { return nullptr; @@ -75,7 +75,7 @@ namespace model { } transfer_amount->set_amount(amount); transfer_amount->set_pubkey(sender_model->getPublicKey(), sender_model->getPublicKeySize()); - *receiver = std::string((const char*)*receiverPublicKey, receiverPublicKey->size()); + *receiver = std::string((const char*)receiverPublicKey->data(), receiverPublicKey->size()); obj->mType = TRANSACTION_TRANSFER; obj->mTransactionSpecific = new TransactionTransfer(memo, obj->mTransactionBody.transfer()); diff --git a/src/cpp/model/gradido/TransactionBody.h b/src/cpp/model/gradido/TransactionBody.h index 6168d2884..5bea7eccd 100644 --- a/src/cpp/model/gradido/TransactionBody.h +++ b/src/cpp/model/gradido/TransactionBody.h @@ -33,7 +33,7 @@ namespace model { //! \brief GradidoTransfer Transaction //! \param group if group.isNull() it is a local transfer, else cross group transfer, //! \param group if group is same as sender group outbound, else inbound - static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr sender, MemoryBin* receiverPublicKey, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId = Poco::Timestamp(), Poco::AutoPtr group = nullptr); + static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr sender, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId = Poco::Timestamp(), Poco::AutoPtr group = nullptr); //! \brief GradidoCreation Transaction static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate); diff --git a/src/cpp/model/gradido/TransactionTransfer.cpp b/src/cpp/model/gradido/TransactionTransfer.cpp index e730262b7..10c693171 100644 --- a/src/cpp/model/gradido/TransactionTransfer.cpp +++ b/src/cpp/model/gradido/TransactionTransfer.cpp @@ -84,19 +84,19 @@ namespace model { if (!sender_user->load((const unsigned char*)sender_pubkey.data())) { sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)sender_pubkey.data(), sender_pubkey.size()); - mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, -amount, true)); - } - else { - mKontoTable.push_back(KontoTableEntry(sender_user->getModel(), -amount, true)); - } - - if (!receiver_user->load((const unsigned char*)receiver_pubkey.data())) { - sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)receiver_pubkey.data(), receiver_pubkey.size()); mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, amount, true)); } else { mKontoTable.push_back(KontoTableEntry(sender_user->getModel(), amount, true)); } + + if (!receiver_user->load((const unsigned char*)receiver_pubkey.data())) { + sodium_bin2hex(pubkeyHexTemp, 65, (const unsigned char*)receiver_pubkey.data(), receiver_pubkey.size()); + mKontoTable.push_back(KontoTableEntry(pubkeyHexTemp, amount, false)); + } + else { + mKontoTable.push_back(KontoTableEntry(receiver_user->getModel(), amount, false)); + } mMinSignatureCount = 1; auto mm = MemoryManager::getInstance(); auto pubkey_copy = mm->getFreeMemory(KeyPairEd25519::getPublicKeySize()); diff --git a/src/cpp/model/table/PendingTask.cpp b/src/cpp/model/table/PendingTask.cpp index 3918ad254..f7c667d0d 100644 --- a/src/cpp/model/table/PendingTask.cpp +++ b/src/cpp/model/table/PendingTask.cpp @@ -126,7 +126,8 @@ namespace model { Poco::Data::Statement select(session); - select << "SELECT id, user_id, hedera_id, request, created, finished, result_json, task_type_id, child_pending_task_id, parent_pending_task_id FROM " << getTableName(); + select << "SELECT id, user_id, hedera_id, request, created, finished, result_json, task_type_id, child_pending_task_id, parent_pending_task_id FROM " + << getTableName() << " order by id"; return select; } @@ -150,7 +151,7 @@ namespace model Poco::Data::Statement insert(session); lock(); insert << "INSERT INTO " << getTableName() - << " (user_id, hedera_id, request, created, task_type_id, child_pending_task_id, parent_pending_task_id) VALUES(?,?,?,?,?,?)" + << " (user_id, hedera_id, request, created, task_type_id, child_pending_task_id, parent_pending_task_id) VALUES(?,?,?,?,?,?,?)" , use(mUserId), use(mHederaId), use(mRequest), use(mCreated), use(mTaskTypeId), use(mChildPendingTaskId), use(mParentPendingTaskId); unlock(); return insert; diff --git a/src/cpp/model/table/PendingTask.h b/src/cpp/model/table/PendingTask.h index fd93920a2..bee90e7a2 100644 --- a/src/cpp/model/table/PendingTask.h +++ b/src/cpp/model/table/PendingTask.h @@ -46,6 +46,7 @@ namespace model { inline std::string getRequestCopy() const { SHARED_LOCK; return std::string((const char*)mRequest.content().data(), mRequest.content().size()); } inline Poco::DateTime getCreated() const { SHARED_LOCK; return mCreated; } inline TaskType getTaskType() const { SHARED_LOCK; return (TaskType)mTaskTypeId; } + inline const char* getTaskTypeString() const { SHARED_LOCK; return typeToString((TaskType)mTaskTypeId); } inline int getChildPendingTaskId() const { SHARED_LOCK; return mChildPendingTaskId; } inline int getParentPendingTaskId() const { SHARED_LOCK; return mParentPendingTaskId; } diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index e3797fcf1..91cfbf7f1 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -7,6 +7,8 @@ #include "../../SingletonManager/MemoryManager.h" +#include "../../controller/Group.h" + using namespace Poco::Data::Keywords; namespace model { @@ -427,6 +429,10 @@ namespace model { addError(new ParamError("User::getJson", "exception by getting role", ex.displayText().data())); sendErrorsAsEmail(); } + auto group = controller::Group::load(mGroupId); + if (!group.isNull()) { + userObj.set("group_alias", group->getModel()->getAlias()); + } unlock(); return userObj; diff --git a/src/cpsp/checkTransaction.cpsp b/src/cpsp/checkTransaction.cpsp index 18c46daed..2b30f8045 100644 --- a/src/cpsp/checkTransaction.cpsp +++ b/src/cpsp/checkTransaction.cpsp @@ -35,6 +35,8 @@ enum PageState { std::string memo = ""; bool hasErrors = false; bool enableLogout = true; + int skip_count = 0; + int pending_task_id = 0; PageState state = PAGE_NO_TRANSACTIONS; @@ -46,10 +48,12 @@ enum PageState { bool transaction_finalize_run = false; bool transaction_finalize_result = false; auto transactions_to_sign = pt->getTransactionsUserMustSign(account_user); + + Poco::AutoPtr pending_task; model::gradido::Transaction* transaction = nullptr; Poco::AutoPtr transaction_body; - if(transactions_to_sign.size() > 0) + if(!form.empty()) { transaction = dynamic_cast(transactions_to_sign[0].get()); transaction_body = transaction->getTransactionBody(); @@ -129,18 +133,28 @@ enum PageState { } } if(abort != "") +/* + auto ok = form.get("ok", ""); + auto abort = form.get("abort", ""); + auto skip = form.get("skip", ""); + auto skip_count_str = form.get("skip-count", "0"); + auto pending_task_id_string = form.get("pending-task-id", ""); + DataTypeConverter::strToInt(skip_count_str, skip_count); + + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(pending_task_id_string, pending_task_id)) + { + // load transaction from pending task manager + pending_task = pt->getPendingTask(pending_task_id); + if(!pending_task.isNull() && pending_task->getModel()->isGradidoTransaction()) +*/ { - // make sure we have the correct transaction - transaction = nullptr; - transaction_body.assign(nullptr); - for(auto it = transactions_to_sign.begin(); it != transactions_to_sign.end(); it++) - { - if((*it)->getModel()->getID() == pending_task_id) { - transaction = dynamic_cast(it->get()); - transaction_body = transaction->getTransactionBody(); - break; - } + transaction = dynamic_cast(pending_task.get()); + if(transaction->hasSigned(account_user)) { + transaction = nullptr; + } else { + transaction_body = transaction->getTransactionBody(); } + if(abort != "") { //mSession->finalizeTransaction(false, true); @@ -148,8 +162,6 @@ enum PageState { if(transaction && transaction->getModel()->getUserId() == user_model->getID()) { transaction->deleteFromDB(); - transaction_body.assign(nullptr); - transactions_to_sign.clear(); transaction = nullptr; } } @@ -177,29 +189,55 @@ enum PageState { } if(!hasErrors) { //mSession->finalizeTransaction(true, false); - if(transaction->sign(account_user)) { - transaction_body.assign(nullptr); - transactions_to_sign.clear(); + if(transaction && transaction->sign(account_user)) { transaction = nullptr; } } } + else if(skip != "") + { + skip_count++; + transaction = nullptr; + } } else { - addError(new Error(gettext("Form Error"), gettext("error with field"))); + addError(new Error(gettext("Input Error"), gettext("Task no found"))); } + } else { + addError(new Error(gettext("Form Error"), gettext("error with field"))); } } + auto transactions_user_must_sign = pt->getTransactionsUserMustSign(account_user); + std::vector> transactions_someone_must_sign; + // TODO: work with community server roles + if(user_model->getRole() == model::table::ROLE_ADMIN) { + transactions_someone_must_sign = pt->getTransactionSomeoneMustSign(account_user); + } + std::vector> transactions_to_sign; + bool transaction_removeable = false; + int transaction_to_sign_index = 0; if(!transaction) { - transactions_to_sign = pt->getTransactionsUserMustSign(account_user); - if(transactions_to_sign.size() > 0) + if(transactions_user_must_sign.size() > skip_count) { + transactions_to_sign = transactions_user_must_sign; + transaction_to_sign_index = skip_count; + } else if(transactions_someone_must_sign.size() > (skip_count - transactions_user_must_sign.size())) { + transactions_to_sign = transactions_someone_must_sign; + transaction_to_sign_index = skip_count - transactions_user_must_sign.size(); + } + + if(transactions_to_sign.size() > transaction_to_sign_index) { - transaction = dynamic_cast(transactions_to_sign[0].get()); + transaction = dynamic_cast(transactions_to_sign[transaction_to_sign_index].get()); transaction_body = transaction->getTransactionBody(); + // user can only delete there own transactions + // TODO: Auto timeout for community transactions + if(transaction->getModel()->getUserId() == user_model->getID()) { + transaction_removeable = true; + } } } - size_t sumTransactions = transactions_to_sign.size(); + size_t sumTransactions = transactions_user_must_sign.size() + transactions_someone_must_sign.size(); if(sumTransactions == 0) { auto lastExternReferer = mSession->getLastReferer(); @@ -216,14 +254,14 @@ enum PageState { return; } - if(sumTransactions > 0) + if(transactions_user_must_sign.size() > 0) { enableLogout = false; } - if(PAGE_NO_TRANSACTIONS == state && sumTransactions > 0) + if(PAGE_NO_TRANSACTIONS == state && transaction && !transaction_body.isNull()) { auto transactionType = transaction_body->getType(); - auto memo = transaction_body->getMemo(); + memo = transaction_body->getMemo(); switch(transactionType) { case model::gradido::TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break; case model::gradido::TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break; @@ -249,11 +287,14 @@ enum PageState { <% } %>
- <% if(sumTransactions > 0) { %> - <%= sumTransactions %> <%= gettext("Transaktionen warten darauf bestätigt zu werden.") %> - <% } else if(state == PAGE_NO_TRANSACTIONS) { %> + <% if(sumTransactions == 0) { %> <%= gettext("Es gibt zurzeit keine Transaktionen zum bestätigen") %> - <% } %> + <% } else { %> +

<%= sumTransactions %> <%= gettext("Transaktionen warten darauf bestätigt zu werden.") %>

+ <% if(skip_count > 0) { %> +

<%= skip_count %> <%= gettext("Transaktionen übersprungen.") %>

+ <% } %> + <% } %>
@@ -340,6 +381,7 @@ enum PageState { <% } else if(PAGE_USER_DATA_CORRUPTED == state) { %>

<%= gettext("Es gibt ein Problem mit deinen gespeicherten Daten, bitte wende dich an den")%><%=gettext("Support") %>

<% } %> + + <% if(PAGE_NO_TRANSACTIONS == state) { %> + <%= gettext("Zurück") %> + <% } else { %> +
+
+ Aktives Konto +
+
+ <%= user_model->getNameWithEmailHtml() %> +
+
+
+
+ Verwendungszweck +
+
+ <%= memo %> +
+
+
+ <% if(transaction) { %> + + <% } %> + + <% if(!account_user->hasPassword()) {%> +
+ + "> +
+ <% } %> + <% if(PAGE_USER_DATA_CORRUPTED != state && user_model->isEmailChecked()) { %> + + <% } %> + <% if(transaction_removeable) { %> + + <% } else { %> + + <% } %> +
+ <% } %>