diff --git a/src/cpp/JSONInterface/JsonGetUserInfos.cpp b/src/cpp/JSONInterface/JsonGetUserInfos.cpp index 5785a6c24..e519c3eba 100644 --- a/src/cpp/JSONInterface/JsonGetUserInfos.cpp +++ b/src/cpp/JSONInterface/JsonGetUserInfos.cpp @@ -1,116 +1,123 @@ -#include "JsonGetUserInfos.h" - -#include "../lib/DataTypeConverter.h" -#include "../SingletonManager/SessionManager.h" -#include "../controller/User.h" -#include "../controller/EmailVerificationCode.h" - -#include "../ServerConfig.h" - -Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params) -{ - /* - 'session_id' => $session_id, - 'email' => $email, - 'ask' => ['EmailOptIn.Register'] - */ - // incoming - int session_id = 0; - std::string email; - Poco::JSON::Array::Ptr askArray; - - auto sm = SessionManager::getInstance(); - - // 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 { - paramJsonObject->get("email").convert(email); - paramJsonObject->get("session_id").convert(session_id); - askArray = paramJsonObject->getArray("ask"); - } - catch (Poco::Exception& ex) { - return stateError("json exception", ex.displayText()); - } - } - else { - return stateError("parameter format unknown"); - } - - if (!session_id) { - return stateError("session_id invalid"); - } - if (askArray.isNull()) { - return stateError("ask is zero or not an array"); - } - - auto session = sm->getSession(session_id); - if (!session) { - return customStateError("not found", "session not found"); - } - - auto user = controller::User::create(); - if (1 != user->load(email)) { - return customStateError("not found", "user not found"); - } - auto userModel = user->getModel(); - - - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", "success"); - Poco::JSON::Array jsonErrorsArray; - Poco::JSON::Object jsonUser; - Poco::JSON::Object jsonServer; - - for (auto it = askArray->begin(); it != askArray->end(); it++) { - auto parameter = *it; - std::string parameterString; - try { - parameter.convert(parameterString); - if (parameterString == "EmailVerificationCode.Register") { - try { - auto emailVerificationCode = controller::EmailVerificationCode::load( - userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER - ); - if (!emailVerificationCode) { - emailVerificationCode = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); - UniLib::controller::TaskPtr insert = new model::table::ModelInsertTask(emailVerificationCode->getModel(), false); - insert->scheduleTask(insert); - } - jsonUser.set("EmailVerificationCode.Register", std::to_string(emailVerificationCode->getModel()->getCode())); - } - catch (Poco::Exception& ex) { - printf("exception: %s\n", ex.displayText().data()); - } - } - else if (parameterString == "loginServer.path") { - jsonServer.set("loginServer.path", ServerConfig::g_serverPath); - } - else if (parameterString == "user.pubkeyhex") { - jsonUser.set("pubkeyhex", userModel->getPublicKeyHex()); - } - else if (parameterString == "user.first_name") { - jsonUser.set("first_name", userModel->getFirstName()); - } - else if (parameterString == "user.last_name") { - jsonUser.set("last_name", userModel->getLastName()); - } - else if (parameterString == "user.disabled") { - jsonUser.set("disabled", userModel->isDisabled()); - } - } - catch (Poco::Exception& ex) { - jsonErrorsArray.add("ask parameter invalid"); - } - } - result->set("errors", jsonErrorsArray); - result->set("userData", jsonUser); - result->set("server", jsonServer); - return result; - +#include "JsonGetUserInfos.h" + +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" +#include "../controller/User.h" +#include "../controller/EmailVerificationCode.h" + +#include "../ServerConfig.h" + +Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params) +{ + /* + 'session_id' => $session_id, + 'email' => $email, + 'ask' => ['EmailOptIn.Register'] + */ + // incoming + int session_id = 0; + std::string email; + Poco::JSON::Array::Ptr askArray; + + auto sm = SessionManager::getInstance(); + + // 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 { + paramJsonObject->get("email").convert(email); + paramJsonObject->get("session_id").convert(session_id); + askArray = paramJsonObject->getArray("ask"); + } + catch (Poco::Exception& ex) { + return stateError("json exception", ex.displayText()); + } + } + else { + return stateError("parameter format unknown"); + } + + if (!session_id) { + return stateError("session_id invalid"); + } + if (askArray.isNull()) { + return stateError("ask is zero or not an array"); + } + + auto session = sm->getSession(session_id); + if (!session) { + return customStateError("not found", "session not found"); + } + + auto user = controller::User::create(); + if (1 != user->load(email)) { + return customStateError("not found", "user not found"); + } + auto userModel = user->getModel(); + + + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "success"); + Poco::JSON::Array jsonErrorsArray; + Poco::JSON::Object jsonUser; + Poco::JSON::Object jsonServer; + + for (auto it = askArray->begin(); it != askArray->end(); it++) { + auto parameter = *it; + std::string parameterString; + try { + parameter.convert(parameterString); + if (parameterString == "EmailVerificationCode.Register") { + try { + auto emailVerificationCode = controller::EmailVerificationCode::load( + userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER + ); + if (!emailVerificationCode) { + emailVerificationCode = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); + UniLib::controller::TaskPtr insert = new model::table::ModelInsertTask(emailVerificationCode->getModel(), false); + insert->scheduleTask(insert); + } + jsonUser.set("EmailVerificationCode.Register", std::to_string(emailVerificationCode->getModel()->getCode())); + } + catch (Poco::Exception& ex) { + printf("exception: %s\n", ex.displayText().data()); + } + } + else if (parameterString == "loginServer.path") { + jsonServer.set("loginServer.path", ServerConfig::g_serverPath); + } + else if (parameterString == "user.pubkeyhex") { + jsonUser.set("pubkeyhex", userModel->getPublicKeyHex()); + } + else if (parameterString == "user.first_name") { + jsonUser.set("first_name", userModel->getFirstName()); + } + else if (parameterString == "user.last_name") { + jsonUser.set("last_name", userModel->getLastName()); + } + else if (parameterString == "user.disabled") { + jsonUser.set("disabled", userModel->isDisabled()); + } + else if (parameterString == "user.email_checked") { + jsonUser.set("email_checked", userModel->isEmailChecked()); + } + else if (parameterString == "user.identHash") { + auto email = userModel->getEmail(); + jsonUser.set("identHash", DRMakeStringHash(email.data(), email.size())); + } + } + catch (Poco::Exception& ex) { + jsonErrorsArray.add("ask parameter invalid"); + } + } + result->set("errors", jsonErrorsArray); + result->set("userData", jsonUser); + result->set("server", jsonServer); + return result; + } \ No newline at end of file diff --git a/src/cpp/JSONInterface/JsonTransaction.cpp b/src/cpp/JSONInterface/JsonTransaction.cpp index 53722423f..62f001469 100644 --- a/src/cpp/JSONInterface/JsonTransaction.cpp +++ b/src/cpp/JSONInterface/JsonTransaction.cpp @@ -58,6 +58,13 @@ Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params) paramJsonObject->get("transaction_base64").convert(transactionBase64String); if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) { + if (auto_sign) { + auto errorJson = session->getErrorsArray(); + result->set("state", "error"); + result->set("msg", "error processing transaction"); + result->set("details", errorJson); + return result; + } auto lastError = session->getLastError(); if (lastError) delete lastError; result->set("state", "error"); diff --git a/src/cpp/tasks/SigningTransaction.cpp b/src/cpp/tasks/SigningTransaction.cpp index d40ec6158..5e1282c48 100644 --- a/src/cpp/tasks/SigningTransaction.cpp +++ b/src/cpp/tasks/SigningTransaction.cpp @@ -1,265 +1,268 @@ -#include "SigningTransaction.h" - -#include - -#include "../SingletonManager/ErrorManager.h" -#include "../SingletonManager/MemoryManager.h" -#include "../SingletonManager/SingletonTaskObserver.h" - -#include "../lib/Profiler.h" - -#include "../proto/gradido/Transaction.pb.h" - -#include "sodium.h" - -#include "../ServerConfig.h" -#include "Poco/JSON/Object.h" -#include "Poco/JSON/Parser.h" -#include "Poco/StreamCopier.h" -#include "Poco/Net/HTTPSClientSession.h" -#include "Poco/Net/HTTPRequest.h" -#include "Poco/Net/HTTPResponse.h" - -SigningTransaction::SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser) - : mProcessingeTransaction(processingeTransaction), mNewUser(newUser) -{ - auto ob = SingletonTaskObserver::getInstance(); - auto email = getUserEmail(); - - if (email != "") { - ob->addTask(email, TASK_OBSERVER_SIGN_TRANSACTION); - } -} - -SigningTransaction::~SigningTransaction() -{ - auto ob = SingletonTaskObserver::getInstance(); - auto email = getUserEmail(); - - if (email != "") { - ob->removeTask(email, TASK_OBSERVER_SIGN_TRANSACTION); - } -} - -std::string SigningTransaction::getUserEmail() -{ - model::table::User* user_model = nullptr; - - if (!mNewUser.isNull()) { - user_model = mNewUser->getModel(); - } - if (user_model) { - return user_model->getEmail(); - } - return ""; -} - -int SigningTransaction::run() { - auto mm = MemoryManager::getInstance(); - - Error* transactionError = new Error("SigningTransaction", mProcessingeTransaction->mProtoMessageBase64.data()); - addError(transactionError, false); - - //= new Error("SigningTransaction start", mProcessingeTransaction->g) - //if (mUser.isNull() || !mUser->hasCryptoKey()) { - if(mNewUser.isNull() || !mNewUser->hasPassword()) { - addError(new Error("SigningTransaction", "user hasn't crypto key or is null")); - sendErrorsAsEmail(); - return -1; - } - - //auto privKey = mUser->getPrivKey(); - //if (!mUser->hasPrivKey()) { - auto gradido_key_pair = mNewUser->getGradidoKeyPair(); - KeyPairEd25519* recovered_gradido_key_pair = nullptr; - if(!gradido_key_pair || !gradido_key_pair->hasPrivateKey()) { - - if (!mNewUser->tryLoadPassphraseUserBackup(&recovered_gradido_key_pair)) { - if(mNewUser->setGradidoKeyPair(recovered_gradido_key_pair)) - { - mNewUser->getModel()->updatePrivkey(); - } - } - else { - addError(new Error("SigningTransaction", "user cannot decrypt private key")); - sendErrorsAsEmail(); - return -2; - } - } - // get body bytes - model::messages::gradido::Transaction transaction; - auto bodyBytes = transaction.mutable_bodybytes(); - *bodyBytes = mProcessingeTransaction->getBodyBytes(); - if (*bodyBytes == "") { - getErrors(mProcessingeTransaction); - sendErrorsAsEmail(); - return -3; - } - // sign - //auto sign = mUser->sign((const unsigned char*)bodyBytes->data(), bodyBytes->size()); - MemoryBin* sign = nullptr; - if (gradido_key_pair) { - sign = gradido_key_pair->sign(*bodyBytes); - } - else if (recovered_gradido_key_pair) { - sign = recovered_gradido_key_pair->sign(*bodyBytes); - } - if (!sign) { - ErrorManager::getInstance()->sendErrorsAsEmail(); - sendErrorsAsEmail(); - mm->releaseMemory(sign); - return -4; - } - - // pubkey for signature - /*auto pubkeyBin = mm->getFreeMemory(ed25519_pubkey_SIZE); - size_t realBin = 0; - if (sodium_hex2bin(*pubkeyBin, *pubkeyBin, pubkeyHex.data(), pubkeyHex.size(), nullptr, &realBin, nullptr)) { - addError(new Error("SigningTransaction", "error in sodium_hex2bin")); - sendErrorsAsEmail(); - mm->releaseMemory(pubkeyBin); - mm->releaseMemory(sign); - return -5; - } - */ - // add to message - auto sigMap = transaction.mutable_sigmap(); - auto sigPair = sigMap->add_sigpair(); - - auto pubkeyBytes = sigPair->mutable_pubkey(); - auto pubkeyBin = mNewUser->getModel()->getPublicKey(); - *pubkeyBytes = std::string((const char*)pubkeyBin, crypto_sign_PUBLICKEYBYTES); - - - auto sigBytes = sigPair->mutable_ed25519(); - *sigBytes = std::string((char*)*sign, sign->size()); - mm->releaseMemory(sign); - - /*std::string protoPrettyPrint; - google::protobuf::TextFormat::PrintToString(transaction, &protoPrettyPrint); - printf("transaction pretty: %s\n", protoPrettyPrint.data()); - model::messages::gradido::TransactionBody transactionBody; - transactionBody.MergeFromString(transaction.bodybytes()); - google::protobuf::TextFormat::PrintToString(transactionBody, &protoPrettyPrint); - printf("transaction body pretty: \n%s\n", protoPrettyPrint.data()); - */ - // finalize - //printf("sigpair size: %d\n", transaction.sigmap().sigpair_size()); - std::string finalTransactionBin = transaction.SerializeAsString(); - if (finalTransactionBin == "") { - addError(new Error("SigningTransaction", "error serializing final transaction")); - sendErrorsAsEmail(); - return -6; - } - - // finale to base64 - auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); - auto finalBase64Bin = mm->getFreeMemory(finalBase64Size); - if (!sodium_bin2base64(*finalBase64Bin, finalBase64Size, (const unsigned char*)finalTransactionBin.data(), finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING)) { - addError(new Error("SigningTransaction", "error convert final transaction to base64")); - sendErrorsAsEmail(); - mm->releaseMemory(finalBase64Bin); - return -7; - } - addError(new Error("Signing transaction final", *finalBase64Bin), false); - - // create json request - - Poco::JSON::Object requestJson; - requestJson.set("method", "putTransaction"); - requestJson.set("transaction", std::string((char*)*finalBase64Bin)); - //printf("\nbase64 transaction: \n%s\n\n", (char*)*finalBase64Bin); - mm->releaseMemory(finalBase64Bin); - - - //std::string request = requestJson.stringify(); - - // send post request via https - // 443 = HTTPS Default - // or http via port 80 if it is a test server - // TODO: adding port into ServerConfig - try { - Profiler phpRequestTime; - Poco::Net::HTTPClientSession* clientSession = nullptr; - if (ServerConfig::g_phpServerPort) { - clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, ServerConfig::g_phpServerPort); - } - else if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || - ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { - clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443); - } - else { - clientSession = new Poco::Net::HTTPClientSession(ServerConfig::g_php_serverHost, 80); - } - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); - - request.setChunkedTransferEncoding(true); - std::ostream& requestStream = clientSession->sendRequest(request); - requestJson.stringify(requestStream); - - Poco::Net::HTTPResponse response; - std::istream& request_stream = clientSession->receiveResponse(response); - - // debugging answer - - std::stringstream responseStringStream; - for (std::string line; std::getline(request_stream, line); ) { - responseStringStream << line << std::endl; - } - Poco::Logger& speedLog= Poco::Logger::get("SpeedLog"); - speedLog.information("[putTransaction] php server time: %s", phpRequestTime.string()); - - // extract parameter from request - Poco::JSON::Parser jsonParser; - Poco::Dynamic::Var parsedJson; - try { - parsedJson = jsonParser.parse(responseStringStream.str()); - } - catch (Poco::Exception& ex) { - //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); - addError(new ParamError("SigningTransaction", "error parsing request answer", ex.displayText().data())); - - FILE* f = fopen("response.html", "wt"); - if (f) { - std::string responseString = responseStringStream.str(); - fwrite(responseString.data(), 1, responseString.size(), f); - fclose(f); - } - // */ - sendErrorsAsEmail(responseStringStream.str()); - return -9; - } - - //sendErrorsAsEmail("HalloRote Test "); - - Poco::JSON::Object object = *parsedJson.extract(); - auto state = object.get("state"); - std::string stateString = state.convert(); - if (stateString == "error") { - addError(new Error("SigningTransaction", "php server return error")); - if (!object.isNull("msg")) { - addError(new ParamError("SigningTransaction", "msg:", object.get("msg").convert().data())); - } - if (!object.isNull("details")) { - addError(new ParamError("SigningTransaction", "details:", object.get("details").convert().data())); - } - if (!object.isNull("user_error")) { - addError(new ParamError("SigningTransaction", "user_error", object.get("user_error").convert().data())); - } - sendErrorsAsEmail(); - return -10; - } - delete clientSession; - //printf("state: %s\n", stateString.data()); - //int zahl = 1; - } - catch (Poco::Exception& e) { - addError(new ParamError("SigningTransaction", "connect error to php server", e.displayText().data())); - printf("url: %s\n", ServerConfig::g_php_serverHost.data()); - sendErrorsAsEmail(); - return -8; - } - - - return 0; +#include "SigningTransaction.h" + +#include + +#include "../SingletonManager/ErrorManager.h" +#include "../SingletonManager/MemoryManager.h" +#include "../SingletonManager/SingletonTaskObserver.h" + +#include "../lib/Profiler.h" + +#include "../proto/gradido/Transaction.pb.h" + +#include "sodium.h" + +#include "../ServerConfig.h" +#include "Poco/JSON/Object.h" +#include "Poco/JSON/Parser.h" +#include "Poco/StreamCopier.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" + +SigningTransaction::SigningTransaction( + Poco::AutoPtr processingeTransaction, + Poco::AutoPtr newUser + , bool sendErrorsToAdmin/* = true*/) + : mProcessingeTransaction(processingeTransaction), mNewUser(newUser), mSendErrorsToAdminEmail(sendErrorsToAdmin) +{ + auto ob = SingletonTaskObserver::getInstance(); + auto email = getUserEmail(); + + if (email != "") { + ob->addTask(email, TASK_OBSERVER_SIGN_TRANSACTION); + } +} + +SigningTransaction::~SigningTransaction() +{ + auto ob = SingletonTaskObserver::getInstance(); + auto email = getUserEmail(); + + if (email != "") { + ob->removeTask(email, TASK_OBSERVER_SIGN_TRANSACTION); + } +} + +std::string SigningTransaction::getUserEmail() +{ + model::table::User* user_model = nullptr; + + if (!mNewUser.isNull()) { + user_model = mNewUser->getModel(); + } + if (user_model) { + return user_model->getEmail(); + } + return ""; +} + +int SigningTransaction::run() { + auto mm = MemoryManager::getInstance(); + + Error* transactionError = new Error("SigningTransaction", mProcessingeTransaction->mProtoMessageBase64.data()); + addError(transactionError, false); + + //= new Error("SigningTransaction start", mProcessingeTransaction->g) + //if (mUser.isNull() || !mUser->hasCryptoKey()) { + if(mNewUser.isNull() || !mNewUser->hasPassword()) { + addError(new Error("SigningTransaction", "user hasn't crypto key or is null")); + if(mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -1; + } + + //auto privKey = mUser->getPrivKey(); + //if (!mUser->hasPrivKey()) { + auto gradido_key_pair = mNewUser->getGradidoKeyPair(); + KeyPairEd25519* recovered_gradido_key_pair = nullptr; + if(!gradido_key_pair || !gradido_key_pair->hasPrivateKey()) { + + if (!mNewUser->tryLoadPassphraseUserBackup(&recovered_gradido_key_pair)) { + if(mNewUser->setGradidoKeyPair(recovered_gradido_key_pair)) + { + mNewUser->getModel()->updatePrivkey(); + } + } + else { + addError(new Error("SigningTransaction", "user cannot decrypt private key")); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -2; + } + } + // get body bytes + model::messages::gradido::Transaction transaction; + auto bodyBytes = transaction.mutable_bodybytes(); + *bodyBytes = mProcessingeTransaction->getBodyBytes(); + if (*bodyBytes == "") { + getErrors(mProcessingeTransaction); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -3; + } + // sign + //auto sign = mUser->sign((const unsigned char*)bodyBytes->data(), bodyBytes->size()); + MemoryBin* sign = nullptr; + if (gradido_key_pair) { + sign = gradido_key_pair->sign(*bodyBytes); + } + else if (recovered_gradido_key_pair) { + sign = recovered_gradido_key_pair->sign(*bodyBytes); + } + if (!sign) { + ErrorManager::getInstance()->sendErrorsAsEmail(); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + mm->releaseMemory(sign); + return -4; + } + + // pubkey for signature + /*auto pubkeyBin = mm->getFreeMemory(ed25519_pubkey_SIZE); + size_t realBin = 0; + if (sodium_hex2bin(*pubkeyBin, *pubkeyBin, pubkeyHex.data(), pubkeyHex.size(), nullptr, &realBin, nullptr)) { + addError(new Error("SigningTransaction", "error in sodium_hex2bin")); + sendErrorsAsEmail(); + mm->releaseMemory(pubkeyBin); + mm->releaseMemory(sign); + return -5; + } + */ + // add to message + auto sigMap = transaction.mutable_sigmap(); + auto sigPair = sigMap->add_sigpair(); + + auto pubkeyBytes = sigPair->mutable_pubkey(); + auto pubkeyBin = mNewUser->getModel()->getPublicKey(); + *pubkeyBytes = std::string((const char*)pubkeyBin, crypto_sign_PUBLICKEYBYTES); + + + auto sigBytes = sigPair->mutable_ed25519(); + *sigBytes = std::string((char*)*sign, sign->size()); + mm->releaseMemory(sign); + + /*std::string protoPrettyPrint; + google::protobuf::TextFormat::PrintToString(transaction, &protoPrettyPrint); + printf("transaction pretty: %s\n", protoPrettyPrint.data()); + model::messages::gradido::TransactionBody transactionBody; + transactionBody.MergeFromString(transaction.bodybytes()); + google::protobuf::TextFormat::PrintToString(transactionBody, &protoPrettyPrint); + printf("transaction body pretty: \n%s\n", protoPrettyPrint.data()); + */ + // finalize + //printf("sigpair size: %d\n", transaction.sigmap().sigpair_size()); + std::string finalTransactionBin = transaction.SerializeAsString(); + if (finalTransactionBin == "") { + addError(new Error("SigningTransaction", "error serializing final transaction")); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -6; + } + + // finale to base64 + auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); + auto finalBase64Bin = mm->getFreeMemory(finalBase64Size); + if (!sodium_bin2base64(*finalBase64Bin, finalBase64Size, (const unsigned char*)finalTransactionBin.data(), finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING)) { + addError(new Error("SigningTransaction", "error convert final transaction to base64")); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + mm->releaseMemory(finalBase64Bin); + return -7; + } + addError(new Error("Signing transaction final", *finalBase64Bin), false); + + // create json request + + Poco::JSON::Object requestJson; + requestJson.set("method", "putTransaction"); + requestJson.set("transaction", std::string((char*)*finalBase64Bin)); + //printf("\nbase64 transaction: \n%s\n\n", (char*)*finalBase64Bin); + mm->releaseMemory(finalBase64Bin); + + + //std::string request = requestJson.stringify(); + + // send post request via https + // 443 = HTTPS Default + // or http via port 80 if it is a test server + // TODO: adding port into ServerConfig + try { + Profiler phpRequestTime; + Poco::Net::HTTPClientSession* clientSession = nullptr; + if (ServerConfig::g_phpServerPort) { + clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, ServerConfig::g_phpServerPort); + } + else if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || + ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { + clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443); + } + else { + clientSession = new Poco::Net::HTTPClientSession(ServerConfig::g_php_serverHost, 80); + } + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); + + request.setChunkedTransferEncoding(true); + std::ostream& requestStream = clientSession->sendRequest(request); + requestJson.stringify(requestStream); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = clientSession->receiveResponse(response); + + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + Poco::Logger& speedLog= Poco::Logger::get("SpeedLog"); + speedLog.information("[putTransaction] php server time: %s", phpRequestTime.string()); + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + } + catch (Poco::Exception& ex) { + //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); + addError(new ParamError("SigningTransaction", "error parsing request answer", ex.displayText().data())); + + FILE* f = fopen("response.html", "wt"); + if (f) { + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + } + // */ + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(responseStringStream.str()); + return -9; + } + + //sendErrorsAsEmail("HalloRote Test "); + + Poco::JSON::Object object = *parsedJson.extract(); + auto state = object.get("state"); + std::string stateString = state.convert(); + if (stateString == "error") { + addError(new Error("SigningTransaction", "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError("SigningTransaction", "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError("SigningTransaction", "details:", object.get("details").convert().data())); + } + if (!object.isNull("user_error")) { + addError(new ParamError("SigningTransaction", "user_error", object.get("user_error").convert().data())); + } + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -10; + } + delete clientSession; + //printf("state: %s\n", stateString.data()); + //int zahl = 1; + } + catch (Poco::Exception& e) { + addError(new ParamError("SigningTransaction", "connect error to php server", e.displayText().data())); + printf("url: %s\n", ServerConfig::g_php_serverHost.data()); + if (mSendErrorsToAdminEmail) sendErrorsAsEmail(); + return -8; + } + + + return 0; } \ No newline at end of file diff --git a/src/cpp/tasks/SigningTransaction.h b/src/cpp/tasks/SigningTransaction.h index 4781052cb..2038c0669 100644 --- a/src/cpp/tasks/SigningTransaction.h +++ b/src/cpp/tasks/SigningTransaction.h @@ -1,45 +1,46 @@ -#ifndef GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE -#define GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE - -#include "CPUTask.h" - -#include "../lib/ErrorList.h" -#include "../model/TransactionBase.h" -#include "../model/User.h" -#include "../controller/User.h" - -#include "../proto/gradido/Transaction.pb.h" - -#include "ProcessingTransaction.h" - -/* -* @author: Dario Rekowski -* -* @date: 28.10.19 -* @desc: Task for signing Transactions -*/ - -class SigningTransaction : public UniLib::controller::CPUTask, public ErrorList -{ -public: - SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser); - virtual ~SigningTransaction(); - - int run(); - - const char* getResourceType() const { return "SigningTransaction"; }; - - - -protected: - Poco::AutoPtr mProcessingeTransaction; - Poco::AutoPtr mNewUser; - -private: - - std::string getUserEmail(); - -}; - - +#ifndef GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE +#define GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE + +#include "CPUTask.h" + +#include "../lib/ErrorList.h" +#include "../model/TransactionBase.h" +#include "../model/User.h" +#include "../controller/User.h" + +#include "../proto/gradido/Transaction.pb.h" + +#include "ProcessingTransaction.h" + +/* +* @author: Dario Rekowski +* +* @date: 28.10.19 +* @desc: Task for signing Transactions +*/ + +class SigningTransaction : public UniLib::controller::CPUTask, public ErrorList +{ +public: + SigningTransaction(Poco::AutoPtr processingeTransaction, Poco::AutoPtr newUser, bool sendErrorsToAdmin = true); + virtual ~SigningTransaction(); + + int run(); + + const char* getResourceType() const { return "SigningTransaction"; }; + + + +protected: + Poco::AutoPtr mProcessingeTransaction; + Poco::AutoPtr mNewUser; + bool mSendErrorsToAdminEmail; + +private: + + std::string getUserEmail(); + +}; + + #endif //GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE \ No newline at end of file