diff --git a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp index e98a02d92..fa99a7b35 100644 --- a/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp +++ b/src/cpp/HTTPInterface/AdminHederaAccountPage.cpp @@ -12,6 +12,8 @@ #include "../controller/HederaId.h" #include "../controller/CryptoKey.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/Success.h" #include "../SingletonManager/SessionManager.h" #include "../ServerConfig.h" @@ -37,12 +39,14 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 20 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 22 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" const char* pageName = "Hedera Account"; auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Profiler hedera_time; + std::string hedera_time_string; Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); @@ -65,7 +69,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { + hedera_time.reset(); hedera_account[0]->updateBalanceFromHedera(user, this); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } } @@ -225,7 +231,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 150 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; @@ -242,37 +248,37 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\t
Aktionen
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t"; -#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) { auto hedera_account_model = (*it)->getModel(); auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID()); responseStream << "\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t\t\t
"; -#line 169 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( (*it)->getHederaId()->getModel()->toString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 170 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getBalanceDouble() ); responseStream << " hbar
\n"; responseStream << "\t\t\t\t\t
"; -#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) ); responseStream << "
\n"; responseStream << "\t\t\t\t\t
"; -#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" responseStream << ( hedera_account_model->getUpdatedString() ); responseStream << "
\n"; responseStream << "\t\t\t\t\t\n"; responseStream << "\t\t\t\t
\n"; responseStream << "\t\t\t"; -#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp" } responseStream << "\n"; responseStream << "\t\t
\n"; responseStream << "\t\n"; @@ -281,7 +287,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t\n"; @@ -295,21 +301,21 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\n"; responseStream << "\t
\n"; diff --git a/src/cpp/HTTPInterface/ElopageWebhook.h b/src/cpp/HTTPInterface/ElopageWebhook.h index bf8ea4efc..77c60b155 100644 --- a/src/cpp/HTTPInterface/ElopageWebhook.h +++ b/src/cpp/HTTPInterface/ElopageWebhook.h @@ -4,7 +4,7 @@ #include "PageRequestMessagedHandler.h" #include "../tasks/CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "Poco/Net/NameValueCollection.h" @@ -14,7 +14,7 @@ public: void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); }; -class HandleElopageRequestTask : public UniLib::controller::CPUTask, protected ErrorList +class HandleElopageRequestTask : public UniLib::controller::CPUTask, protected NotificationList { public: HandleElopageRequestTask(Poco::Net::NameValueCollection& requestData); diff --git a/src/cpp/HTTPInterface/PageRequestMessagedHandler.h b/src/cpp/HTTPInterface/PageRequestMessagedHandler.h index 2e47b398d..396fc8a4e 100644 --- a/src/cpp/HTTPInterface/PageRequestMessagedHandler.h +++ b/src/cpp/HTTPInterface/PageRequestMessagedHandler.h @@ -2,7 +2,7 @@ #define PAGE_REQUEST_MESSAGE_HANDLER_INCLUDED #include "../model/Session.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/Profiler.h" #include "../SingletonManager/LanguageManager.h" @@ -11,7 +11,7 @@ #include "Poco/Net/HTMLForm.h" #include "Poco/RegularExpression.h" -class PageRequestMessagedHandler : public Poco::Net::HTTPRequestHandler, public ErrorList +class PageRequestMessagedHandler : public Poco::Net::HTTPRequestHandler, public NotificationList { public: PageRequestMessagedHandler() {} diff --git a/src/cpp/JSONInterface/JsonRequestHandler.cpp b/src/cpp/JSONInterface/JsonRequestHandler.cpp index b66cba495..1601c764c 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandler.cpp @@ -1,141 +1,138 @@ -#include "JsonRequestHandler.h" - -#include "Poco/Net/HTTPServerRequest.h" -#include "Poco/Net/HTTPServerResponse.h" - -#include "Poco/URI.h" -#include "Poco/DeflatingStream.h" - -#include "Poco/JSON/Parser.h" - -#include "../ServerConfig.h" - -#include "../lib/DataTypeConverter.h" -#include "../SingletonManager/SessionManager.h" - - -void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) -{ - - response.setChunkedTransferEncoding(false); - response.setContentType("application/json"); - if (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_CORS_ALL) { - response.set("Access-Control-Allow-Origin", "*"); - response.set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); - } - //bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); - //if (_compressResponse) response.set("Content-Encoding", "gzip"); - - std::ostream& responseStream = response.send(); - //Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); - //std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; - - auto method = request.getMethod(); - std::istream& request_stream = request.stream(); - Poco::JSON::Object* json_result = nullptr; - if (method == "POST" || method == "PUT") { - // extract parameter from request - Poco::Dynamic::Var parsedResult = parseJsonWithErrorPrintFile(request_stream); - - if (parsedResult.size() != 0) { - json_result = handle(parsedResult); - } - else { - json_result = stateError("empty body"); - } - - } - else if(method == "GET") { - Poco::URI uri(request.getURI()); - auto queryParameters = uri.getQueryParameters(); - json_result = handle(queryParameters); - } - - if (json_result) { - if (!json_result->isNull("session_id")) { - int session_id = 0; - try { - json_result->get("session_id").convert(session_id); - } - catch (Poco::Exception& e) { - ErrorList erros; - erros.addError(new Error("json request", "invalid session_id")); - erros.sendErrorsAsEmail(); - } - if (session_id) { - auto session = SessionManager::getInstance()->getSession(session_id); - response.addCookie(session->getLoginCookie()); - } - } - json_result->stringify(responseStream); - delete json_result; - } - - //if (_compressResponse) _gzipStream.close(); -} - - -Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& request_stream, ErrorList* errorHandler /* = nullptr*/, const char* functionName /* = nullptr*/) -{ - // debugging answer - - std::stringstream responseStringStream; - for (std::string line; std::getline(request_stream, line); ) { - responseStringStream << line << std::endl; - } - - // extract parameter from request - Poco::JSON::Parser jsonParser; - Poco::Dynamic::Var parsedJson; - try { - parsedJson = jsonParser.parse(responseStringStream.str()); - - return parsedJson; - } - catch (Poco::Exception& ex) { - if (errorHandler) { - errorHandler->addError(new ParamError(functionName, "error parsing request answer", ex.displayText().data())); - errorHandler->sendErrorsAsEmail(responseStringStream.str()); - } - std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d_%m_%yT%H_%M_%S"); - std::string filename = dateTimeString + "_response.html"; - FILE* f = fopen(filename.data(), "wt"); - if (f) { - std::string responseString = responseStringStream.str(); - fwrite(responseString.data(), 1, responseString.size(), f); - fclose(f); - } - return Poco::Dynamic::Var(); - } - return Poco::Dynamic::Var(); -} - -Poco::JSON::Object* JsonRequestHandler::stateError(const char* msg, std::string details) -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", "error"); - result->set("msg", msg); - if (details != "") { - result->set("details", details); - } - return result; -} - -Poco::JSON::Object* JsonRequestHandler::stateSuccess() -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", "success"); - return result; -} - -Poco::JSON::Object* JsonRequestHandler::customStateError(const char* state, const char* msg, std::string details/* = ""*/) -{ - Poco::JSON::Object* result = new Poco::JSON::Object; - result->set("state", state); - result->set("msg", msg); - if (details != "") { - result->set("details", details); - } - return result; -} - +#include "JsonRequestHandler.h" + +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" + +#include "Poco/URI.h" +#include "Poco/DeflatingStream.h" + +#include "Poco/JSON/Parser.h" + +#include "../ServerConfig.h" + +#include "../lib/DataTypeConverter.h" +#include "../SingletonManager/SessionManager.h" + +void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + + response.setChunkedTransferEncoding(false); + response.setContentType("application/json"); + if (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_CORS_ALL) { + response.set("Access-Control-Allow-Origin", "*"); + response.set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); + } + //bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + //if (_compressResponse) response.set("Content-Encoding", "gzip"); + + std::ostream& responseStream = response.send(); + //Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + //std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + + auto method = request.getMethod(); + std::istream& request_stream = request.stream(); + Poco::JSON::Object* json_result = nullptr; + if (method == "POST" || method == "PUT") { + // extract parameter from request + Poco::Dynamic::Var parsedResult = parseJsonWithErrorPrintFile(request_stream); + + if (parsedResult.size() != 0) { + json_result = handle(parsedResult); + } + else { + json_result = stateError("empty body"); + } + } + else if(method == "GET") { + Poco::URI uri(request.getURI()); + auto queryParameters = uri.getQueryParameters(); + json_result = handle(queryParameters); + } + + if (json_result) { + if (!json_result->isNull("session_id")) { + int session_id = 0; + try { + json_result->get("session_id").convert(session_id); + } + catch (Poco::Exception& e) { + ErrorList erros; + erros.addError(new Error("json request", "invalid session_id")); + erros.sendErrorsAsEmail(); + } + if (session_id) { + auto session = SessionManager::getInstance()->getSession("session_id"); + response.addCookie(session->getLoginCookie()); + } + } + json_result->stringify(responseStream); + delete json_result; + } + + //if (_compressResponse) _gzipStream.close(); +} + + +Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& request_stream, NotificationList* errorHandler /* = nullptr*/, const char* functionName /* = nullptr*/) +{ + // debugging answer + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + try { + parsedJson = jsonParser.parse(responseStringStream.str()); + + return parsedJson; + } + catch (Poco::Exception& ex) { + if (errorHandler) { + errorHandler->addError(new ParamError(functionName, "error parsing request answer", ex.displayText().data())); + errorHandler->sendErrorsAsEmail(responseStringStream.str()); + } + std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d_%m_%yT%H_%M_%S"); + std::string filename = dateTimeString + "_response.html"; + FILE* f = fopen(filename.data(), "wt"); + if (f) { + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + } + return Poco::Dynamic::Var(); + } + return Poco::Dynamic::Var(); +} + +Poco::JSON::Object* JsonRequestHandler::stateError(const char* msg, std::string details) +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "error"); + result->set("msg", msg); + if (details != "") { + result->set("details", details); + } + return result; +} + +Poco::JSON::Object* JsonRequestHandler::stateSuccess() +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", "success"); + return result; +} + +Poco::JSON::Object* JsonRequestHandler::customStateError(const char* state, const char* msg, std::string details/* = ""*/) +{ + Poco::JSON::Object* result = new Poco::JSON::Object; + result->set("state", state); + result->set("msg", msg); + if (details != "") { + result->set("details", details); + } + return result; +} diff --git a/src/cpp/JSONInterface/JsonRequestHandler.h b/src/cpp/JSONInterface/JsonRequestHandler.h index 72230bfe4..90c3e3171 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.h +++ b/src/cpp/JSONInterface/JsonRequestHandler.h @@ -4,7 +4,7 @@ #include "Poco/Net/HTTPRequestHandler.h" #include "Poco/JSON/Object.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" class JsonRequestHandler : public Poco::Net::HTTPRequestHandler @@ -15,7 +15,7 @@ public: virtual Poco::JSON::Object* handle(Poco::Dynamic::Var params) = 0; - static Poco::Dynamic::Var parseJsonWithErrorPrintFile(std::istream& request_stream, ErrorList* errorHandler = nullptr, const char* functionName = nullptr); + static Poco::Dynamic::Var parseJsonWithErrorPrintFile(std::istream& request_stream, NotificationList* errorHandler = nullptr, const char* functionName = nullptr); protected: Poco::JSON::Object* mResultJson; diff --git a/src/cpp/SingletonManager/ConnectionManager.h b/src/cpp/SingletonManager/ConnectionManager.h index 72c8b02e4..2c0d4968a 100644 --- a/src/cpp/SingletonManager/ConnectionManager.h +++ b/src/cpp/SingletonManager/ConnectionManager.h @@ -9,7 +9,7 @@ #include "../MySQL/Poco/Connector.h" #include "Poco/Exception.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" enum ConnectionType { CONNECTION_MYSQL_LOGIN_SERVER, @@ -17,7 +17,7 @@ enum ConnectionType { CONNECTION_MAX }; -class ConnectionManager : public ErrorList +class ConnectionManager : public NotificationList { public: ~ConnectionManager(); diff --git a/src/cpp/SingletonManager/ErrorManager.cpp b/src/cpp/SingletonManager/ErrorManager.cpp index 090a6f9dd..b4df67974 100644 --- a/src/cpp/SingletonManager/ErrorManager.cpp +++ b/src/cpp/SingletonManager/ErrorManager.cpp @@ -4,7 +4,7 @@ #include "Poco/Net/SecureSMTPClientSession.h" #include "Poco/Net/StringPartSource.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../model/email/Email.h" @@ -34,19 +34,19 @@ ErrorManager::~ErrorManager() mErrorsMap.clear(); } -void ErrorManager::addError(Error* error, bool log/* = true*/) +void ErrorManager::addError(Notification* error, bool log/* = true*/) { DHASH id = DRMakeStringHash(error->getFunctionName()); mWorkingMutex.lock(); auto it = mErrorsMap.find(id); - std::list* list = nullptr; + std::list* list = nullptr; //printf("[ErrorManager::addError] error with function: %s, %s\n", error->getFunctionName(), error->getMessage()); if(log) mLogging.error("[ErrorManager::addError] %s", error->getString(false)); if (it == mErrorsMap.end()) { - list = new std::list; - mErrorsMap.insert(std::pair*>(id, list)); + list = new std::list; + mErrorsMap.insert(std::pair*>(id, list)); } else { list = it->second; @@ -62,9 +62,9 @@ void ErrorManager::addError(Error* error, bool log/* = true*/) } -int ErrorManager::getErrors(ErrorList* send) +int ErrorManager::getErrors(NotificationList* send) { - Error* error = nullptr; + Notification* error = nullptr; int iCount = 0; while (error = send->getLastError()) { addError(error, false); diff --git a/src/cpp/SingletonManager/ErrorManager.h b/src/cpp/SingletonManager/ErrorManager.h index e59bd7d35..a0e427d9e 100644 --- a/src/cpp/SingletonManager/ErrorManager.h +++ b/src/cpp/SingletonManager/ErrorManager.h @@ -15,7 +15,7 @@ #include #include #include -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/DRHash.h" #include "../tasks/CPUTask.h" @@ -24,7 +24,7 @@ #include "Poco/Net/MailMessage.h" -class ErrorManager : public IErrorCollection +class ErrorManager : public INotificationCollection { public: ~ErrorManager(); @@ -32,9 +32,9 @@ public: static ErrorManager* getInstance(); // will called delete on error - virtual void addError(Error* error, bool log = true); + virtual void addError(Notification* error, bool log = true); - int getErrors(ErrorList* send); + int getErrors(NotificationList* send); virtual void sendErrorsAsEmail(); @@ -43,7 +43,7 @@ protected: // access mutex Poco::Mutex mWorkingMutex; - std::map*> mErrorsMap; + std::map*> mErrorsMap; // how many errors should be stored // poco logging diff --git a/src/cpp/SingletonManager/SessionManager.cpp b/src/cpp/SingletonManager/SessionManager.cpp index 1f7e87303..1eb9c436c 100644 --- a/src/cpp/SingletonManager/SessionManager.cpp +++ b/src/cpp/SingletonManager/SessionManager.cpp @@ -175,7 +175,7 @@ Session* SessionManager::getNewSession(int* handle) } } else { - ErrorList errors; + NotificationList errors; errors.addError(new Error(functionName, "found dead locked session, keeping in memory without reference")); errors.addError(new ParamError(functionName, "last succeeded lock:", result->getLastSucceededLock().data())); errors.sendErrorsAsEmail(); @@ -249,7 +249,7 @@ bool SessionManager::releaseSession(int requestHandleSession) session->setActive(false); } else { - ErrorList errors; + NotificationList errors; errors.addError(new Error("SessionManager::releaseSession", "found dead locked session")); errors.sendErrorsAsEmail(); mRequestSessionMap.erase(requestHandleSession); @@ -590,7 +590,7 @@ void SessionManager::deleteLoginCookies(Poco::Net::HTTPServerRequest& request, P //session_id = atoi(cookies.get("GRADIDO_LOGIN").data()); } -bool SessionManager::checkPwdValidation(const std::string& pwd, ErrorList* errorReciver) +bool SessionManager::checkPwdValidation(const std::string& pwd, NotificationList* errorReciver) { if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) == ServerConfig::UNSECURE_ALLOW_ALL_PASSWORDS) { return true; diff --git a/src/cpp/SingletonManager/SessionManager.h b/src/cpp/SingletonManager/SessionManager.h index e1469d539..9b83c712d 100644 --- a/src/cpp/SingletonManager/SessionManager.h +++ b/src/cpp/SingletonManager/SessionManager.h @@ -69,7 +69,7 @@ public: bool isValid(const std::string& subject, SessionValidationTypes validationType); //! \return true if password is valid - bool checkPwdValidation(const std::string& pwd, ErrorList* errorReciver); + bool checkPwdValidation(const std::string& pwd, NotificationList* errorReciver); void checkTimeoutSession(); diff --git a/src/cpp/controller/HederaAccount.cpp b/src/cpp/controller/HederaAccount.cpp index 57cb14672..6fabe2848 100644 --- a/src/cpp/controller/HederaAccount.cpp +++ b/src/cpp/controller/HederaAccount.cpp @@ -73,7 +73,7 @@ namespace controller { return resultVector; } - bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver/* = nullptr*/) + bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver/* = nullptr*/) { static const char* functionName = "HederaAccount::updateBalanceFromHedera"; @@ -86,27 +86,45 @@ namespace controller { auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType())); auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId()); if (crypto_key.isNull()) { - printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); + if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));} + else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); } return false; } auto hedera_key_pair = crypto_key->getKeyPair(user); if (!hedera_key_pair) { + if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));} printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID()); return false; } + auto query = model::hedera::Query::getBalance(mHederaID, hedera_node); + if (!query) { printf("[%s] error creating query\n", functionName); } query->sign(std::move(hedera_key_pair)); HederaRequest request; + model::hedera::Response response; try { - request.request(query); + if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response) && proto::OK == response.getResponseCode()) { + account_model->updateIntoDB("balance", response.getAccountBalance()); + } + else { + if (errorReceiver) { + errorReceiver->addError(new Error("Hedera", "Hedera request failed")); + errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode()))); + } + else { + printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data()); + } + } + //request.requestViaPHPRelay(query); } catch (Poco::Exception& ex) { printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data()); } + if (errorReceiver) { errorReceiver->getErrors(&request); } diff --git a/src/cpp/controller/HederaAccount.h b/src/cpp/controller/HederaAccount.h index 7f08adddc..d76420b78 100644 --- a/src/cpp/controller/HederaAccount.h +++ b/src/cpp/controller/HederaAccount.h @@ -27,7 +27,7 @@ namespace controller { inline void setHederaId(Poco::AutoPtr hederaId) { mHederaID = hederaId; } inline Poco::AutoPtr getHederaId() { return mHederaID; } - bool updateBalanceFromHedera(Poco::AutoPtr user, ErrorList* errorReceiver = nullptr); + bool updateBalanceFromHedera(Poco::AutoPtr user, NotificationList* errorReceiver = nullptr); protected: HederaAccount(model::table::HederaAccount* dbModel); diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 32c6772c6..308ffa5e8 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -9,6 +9,7 @@ #include #include + HederaRequest::HederaRequest() { @@ -19,29 +20,62 @@ HederaRequest::~HederaRequest() } -HederaRequestReturn HederaRequest::request(model::hedera::Query* query) +HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee/* = 0*/) { auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials()); + grpc::ClientContext context; std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + - std::chrono::milliseconds(10000); + std::chrono::milliseconds(5000); context.set_deadline(deadline); - grpc::CompletionQueue cq; + //grpc::CompletionQueue cq; auto proto_query = query->getProtoQuery(); + auto proto_query_serialized = proto_query->SerializeAsString(); - auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); - printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); - proto::Response* response = nullptr; + //auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size()); + //printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data()); + + auto proto_response = response->getResponsePtr(); + auto connect_string = query->getConnectionString(); + if (proto_query->has_cryptogetaccountbalance()) { - auto stub = proto::CryptoService::NewStub(channel); - auto connect_string = query->getConnectionString(); - printf("try connection to hedera with: %s\n", connect_string.data()); - //auto stream = stub->PrepareAsynccryptoGetBalance(&context, *proto_query, &cq); - auto status = stub->cryptoGetBalance(&context, *proto_query, response); - //stream->StartCall(); - addError(new ParamError("Hedera Request", "crypto get balance", status.error_message())); - printf("[HederaRequest::request] error details: %s\n", status.error_details().data()); + auto stub = proto::CryptoService::NewStub(channel); + // crypto account get balance currently hasn't fees + query->setResponseType(proto::ANSWER_ONLY); + + auto status = stub->cryptoGetBalance(&context, *proto_query, proto_response); + if (status.ok()) { + return HEDERA_REQUEST_RETURN_OK; + } + else { + addError(new ParamError("Hedera Request", "crypto get balance error message:", status.error_message())); + addError(new ParamError("Hedera Request", "details: ", status.error_details())); + return HEDERA_REQUEST_RETURN_ERROR; + } + + } return HEDERA_REQUEST_RETURN_OK; +} + +#include "Poco/JSON/Object.h" +#include "../lib/JsonRequest.h" + +HederaRequestReturn HederaRequest::requestViaPHPRelay(model::hedera::Query* query) +{ + JsonRequest phpRelay("***REMOVED***", 88); + Poco::Net::NameValueCollection parameters; + std::string query_string = query->getProtoQuery()->SerializeAsString(); + //auto query_base64 = DataTypeConverter::binToBase64((const unsigned char*)query_string.data(), query_string.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING); + //auto findPos = query_string.find_first_of("\u"); + auto query_hex = DataTypeConverter::binToHex((const unsigned char*)query_string.data(), query_string.size()); + parameters.set("content", query_hex.substr(0, query_hex.size()-1)); + parameters.set("server", query->getConnectionString()); + parameters.set("method", "getBalance"); + parameters.set("service", "crypto"); + phpRelay.requestGRPCRelay(parameters); + //phpRelay.request("") + + return HEDERA_REQUEST_RETURN_OK; } \ No newline at end of file diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 692215f8d..327ee7634 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -12,6 +12,8 @@ #include "../controller/NodeServer.h" #include "../model/hedera/Query.h" +#include "../model/hedera/Transaction.h" +#include "../model/hedera/Response.h" enum HederaRequestReturn { @@ -22,13 +24,15 @@ enum HederaRequestReturn }; // NodeServerConnection -class HederaRequest : public ErrorList +class HederaRequest : public NotificationList { public: HederaRequest(); ~HederaRequest(); - HederaRequestReturn request(model::hedera::Query* query); + HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); + //! for testing, didn't work server say invalid json :/ + HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query); protected: diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index a97cb8d0e..72e6aceb8 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -138,18 +138,17 @@ namespace DataTypeConverter } - std::string binToBase64(const MemoryBin* data) + std::string binToBase64(const unsigned char* data, size_t size, int variant /*= sodium_base64_VARIANT_ORIGINAL*/) { auto mm = MemoryManager::getInstance(); - size_t binSize = data->size(); - size_t encodedSize = sodium_base64_encoded_len(binSize, sodium_base64_VARIANT_ORIGINAL); - + + size_t encodedSize = sodium_base64_encoded_len(size, variant); auto base64 = mm->getFreeMemory(encodedSize); memset(*base64, 0, encodedSize); size_t resultBinSize = 0; - if (0 != sodium_bin2base64(*base64, encodedSize, *data, binSize, sodium_base64_VARIANT_ORIGINAL)) { + if (nullptr == sodium_bin2base64(*base64, encodedSize, data, size, variant)) { mm->releaseMemory(base64); return ""; } diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index 0dad46954..d970d697d 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -9,6 +9,8 @@ #include "Poco/Data/LOB.h" #include "../SingletonManager/LanguageManager.h" +#include "sodium.h" + namespace DataTypeConverter { enum NumberParseState @@ -25,8 +27,9 @@ namespace DataTypeConverter { MemoryBin* hexToBin(const std::string& hexString); MemoryBin* base64ToBin(const std::string& base64String); - std::string binToBase64(const MemoryBin* data); + std::string binToBase64(const unsigned char* data, size_t size, int variant = sodium_base64_VARIANT_ORIGINAL); + inline std::string binToBase64(const MemoryBin* data, int variant = sodium_base64_VARIANT_ORIGINAL) { return binToBase64(data->data(), data->size(), variant); } std::string binToHex(const unsigned char* data, size_t size); std::string binToHex(const Poco::Nullable& nullableBin); diff --git a/src/cpp/lib/Error.cpp b/src/cpp/lib/Error.cpp index c44f48711..9897d7930 100644 --- a/src/cpp/lib/Error.cpp +++ b/src/cpp/lib/Error.cpp @@ -2,7 +2,7 @@ Error::Error(const char* functionName, const char* message) - : mFunctionName(functionName), mMessage(message) + : Notification(functionName, message) { } @@ -12,7 +12,7 @@ Error::~Error() } -std::string Error::getString(bool withNewline/* = true*/) +std::string Error::getString(bool withNewline/* = true*/) const { std::stringstream ss; ss << mFunctionName << ": " << mMessage; @@ -20,7 +20,7 @@ std::string Error::getString(bool withNewline/* = true*/) return ss.str(); } -std::string Error::getHtmlString() +std::string Error::getHtmlString() const { std::stringstream ss; ss << mFunctionName << ": " << mMessage; @@ -28,7 +28,7 @@ std::string Error::getHtmlString() return ss.str(); } -std::string ParamError::getString(bool withNewline/* = true*/) +std::string ParamError::getString(bool withNewline/* = true*/) const { std::stringstream ss; ss << mFunctionName << ": " << mMessage << " " << mParam; @@ -36,7 +36,7 @@ std::string ParamError::getString(bool withNewline/* = true*/) return ss.str(); } -std::string ParamError::getHtmlString() +std::string ParamError::getHtmlString() const { std::stringstream ss; ss << mFunctionName << ": " << mMessage << " " << mParam << std::endl; diff --git a/src/cpp/lib/Error.h b/src/cpp/lib/Error.h index 2a4d79e85..bf4805da9 100644 --- a/src/cpp/lib/Error.h +++ b/src/cpp/lib/Error.h @@ -1,63 +1,65 @@ -/*! -* -* \author: einhornimmond -* -* \date: 07.03.19 -* -* \brief: error data -*/ - -#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_H -#define DR_LUA_WEB_MODULE_ERROR_ERROR_H - -#include -#include - -class Error -{ -public: - Error(const char* functionName, const char* message); - ~Error(); - - const char* getFunctionName() { return mFunctionName.data(); } - const char* getMessage() { return mMessage.data(); } - virtual std::string getString(bool withNewline = true); - virtual std::string getHtmlString(); - - - -protected: - std::string mFunctionName; - std::string mMessage; -}; - -class ParamError : public Error -{ -public: - ParamError(const char* functionName, const char* message, const char* param) - : Error(functionName, message), mParam(param) {} - ParamError(const char* functionName, const char* message, const std::string& param) - : Error(functionName, message), mParam(param) {} - - ParamError(const char* functioName, const char* message, int param) - : Error(functioName, message) { - std::stringstream ss; - ss << param; - mParam = ss.str(); - } - - virtual std::string getString(bool withNewline = true); - virtual std::string getHtmlString(); -protected: - std::string mParam; -}; - - - -class IErrorCollection -{ -public: - virtual void addError(Error*, bool log = true) = 0; -}; - -#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_H +/*! +* +* \author: einhornimmond +* +* \date: 07.03.19 +* +* \brief: error data +*/ + +#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_H +#define DR_LUA_WEB_MODULE_ERROR_ERROR_H + +#include "Notification.h" +#include +#include + + +class Error : public Notification +{ +public: + Error(const char* functionName, const char* message); + ~Error(); + + const char* getFunctionName() { return mFunctionName.data(); } + const char* getMessage() { return mMessage.data(); } + virtual std::string getString(bool withNewline = true) const; + virtual std::string getHtmlString() const; + + virtual bool isError() { return true; } + +protected: + std::string mFunctionName; + std::string mMessage; +}; + +class ParamError : public Error +{ +public: + ParamError(const char* functionName, const char* message, const char* param) + : Error(functionName, message), mParam(param) {} + ParamError(const char* functionName, const char* message, const std::string& param) + : Error(functionName, message), mParam(param) {} + + ParamError(const char* functioName, const char* message, int param) + : Error(functioName, message) { + std::stringstream ss; + ss << param; + mParam = ss.str(); + } + + virtual std::string getString(bool withNewline = true) const; + virtual std::string getHtmlString() const; +protected: + std::string mParam; +}; + + + +class INotificationCollection +{ +public: + virtual void addError(Notification*, bool log = true) = 0; +}; + +#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_H diff --git a/src/cpp/lib/JsonRequest.cpp b/src/cpp/lib/JsonRequest.cpp index 3e05fa85a..c5dff9281 100644 --- a/src/cpp/lib/JsonRequest.cpp +++ b/src/cpp/lib/JsonRequest.cpp @@ -37,7 +37,6 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::Net:: try { Profiler phpRequestTime; Poco::Net::HTTPSClientSession httpsClientSession(mServerHost, mServerPort); - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); request.setChunkedTransferEncoding(true); @@ -101,5 +100,95 @@ JsonRequestReturn JsonRequest::request(const char* methodName, const Poco::Net:: return JSON_REQUEST_CONNECT_ERROR; } + return JSON_REQUEST_RETURN_OK; +} +#include "Poco/JSON/Stringifier.h" +JsonRequestReturn JsonRequest::requestGRPCRelay(const Poco::Net::NameValueCollection& payload) +{ + static const char* functionName = "JsonRequest::requestGRPCRelay"; + Poco::JSON::Object requestJson; + + for (auto it = payload.begin(); it != payload.end(); it++) { + requestJson.set(it->first, it->second); + } + + // send post request via https + // 443 = HTTPS Default + // TODO: adding port into ServerConfig + try { + Profiler phpRequestTime; + Poco::Net::HTTPClientSession httpClientSession(mServerHost, mServerPort); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/hedera_rpc_relay/gRPCProxy.php"); + + request.setChunkedTransferEncoding(false); + std::ostream& requestStream = httpClientSession.sendRequest(request); + requestJson.stringify(requestStream); + + std::stringstream ss; + requestJson.stringify(ss); + auto f = fopen("grpc.txt", "wt"); + std::string grpc = ss.str(); + fwrite(grpc.data(), grpc.size(), 1, f); + fclose(f); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = httpClientSession.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("[gRPC relay] 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) { + addError(new ParamError(functionName, "error parsing request answer grpc relay", ex.displayText().data())); + + std::string fileName = "response_grpc_"; + fileName += ".html"; + + FILE* f = fopen(fileName.data(), "wt"); + std::string responseString = responseStringStream.str(); + fwrite(responseString.data(), 1, responseString.size(), f); + fclose(f); + // */ + sendErrorsAsEmail(responseStringStream.str()); + return JSON_REQUEST_RETURN_PARSE_ERROR; + } + + Poco::JSON::Object object = *parsedJson.extract(); + auto state = object.get("state"); + std::string stateString = state.convert(); + if (stateString == "error") { + addError(new Error(functionName, "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError(functionName, "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError(functionName, "details:", object.get("details").convert().data())); + } + sendErrorsAsEmail(); + return JSON_REQUEST_RETURN_ERROR; + } + ss.clear(); + Poco::JSON::Stringifier::stringify(object, ss); + printf("json request result: %s\n", ss.str().data()); + } + catch (Poco::Exception& e) { + addError(new ParamError(functionName, "connect error to php server", e.displayText().data())); + sendErrorsAsEmail(); + return JSON_REQUEST_CONNECT_ERROR; + } + + + return JSON_REQUEST_RETURN_OK; } \ No newline at end of file diff --git a/src/cpp/lib/JsonRequest.h b/src/cpp/lib/JsonRequest.h index 87350c002..e13046594 100644 --- a/src/cpp/lib/JsonRequest.h +++ b/src/cpp/lib/JsonRequest.h @@ -8,7 +8,7 @@ * */ -#include "ErrorList.h" +#include "NotificationList.h" #include "Poco/Net/NameValueCollection.h" #ifndef __GRADIDO_LOGIN_SERVER_LIB_JSON_REQUEST_ @@ -22,17 +22,19 @@ enum JsonRequestReturn JSON_REQUEST_CONNECT_ERROR }; -class JsonRequest : public ErrorList +class JsonRequest : public NotificationList { public: JsonRequest(const std::string& serverHost, int serverPort); ~JsonRequest(); JsonRequestReturn request(const char* methodName, const Poco::Net::NameValueCollection& payload); + JsonRequestReturn requestGRPCRelay(const Poco::Net::NameValueCollection& payload); protected: int mServerPort; std::string mServerHost; + }; diff --git a/src/cpp/lib/MultithreadContainer.cpp b/src/cpp/lib/MultithreadContainer.cpp index fc72593a1..d73a6a882 100644 --- a/src/cpp/lib/MultithreadContainer.cpp +++ b/src/cpp/lib/MultithreadContainer.cpp @@ -1,5 +1,5 @@ #include "MultithreadContainer.h" -#include "ErrorList.h" +#include "NotificationList.h" namespace UniLib { namespace lib { @@ -14,7 +14,7 @@ namespace UniLib { } } catch (Poco::TimeoutException& ex) { - ErrorList errors; + NotificationList errors; errors.addError(new ParamError(functionName, "lock timeout", ex.displayText())); if (mLastSucceededLock != "") { errors.addError(new ParamError(functionName, "last succeed lock by ", mLastSucceededLock.data())); diff --git a/src/cpp/lib/Notification.cpp b/src/cpp/lib/Notification.cpp new file mode 100644 index 000000000..15d622923 --- /dev/null +++ b/src/cpp/lib/Notification.cpp @@ -0,0 +1,7 @@ +#include "Notification.h" + +Notification::Notification(const char* functionName, const char* message) + : mFunctionName(functionName), mMessage(message) +{ + +} \ No newline at end of file diff --git a/src/cpp/lib/Notification.h b/src/cpp/lib/Notification.h new file mode 100644 index 000000000..419b861bc --- /dev/null +++ b/src/cpp/lib/Notification.h @@ -0,0 +1,24 @@ +#ifndef GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H +#define GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H + +#include + +class Notification +{ +public: + Notification(const char* functionName, const char* message); + + const char* getFunctionName() { return mFunctionName.data(); } + const char* getMessage() { return mMessage.data(); } + virtual std::string getString(bool withNewline = true) const = 0; + virtual std::string getHtmlString() const = 0; + + virtual bool isError() { return false; } + virtual bool isSuccess() { return false; } + +protected: + std::string mFunctionName; + std::string mMessage; +}; + +#endif //GRADIDO_LOGIN_SERVER_LIB_NOTIFICATION_H \ No newline at end of file diff --git a/src/cpp/lib/ErrorList.cpp b/src/cpp/lib/NotificationList.cpp similarity index 74% rename from src/cpp/lib/ErrorList.cpp rename to src/cpp/lib/NotificationList.cpp index a663b67b2..e355d1597 100644 --- a/src/cpp/lib/ErrorList.cpp +++ b/src/cpp/lib/NotificationList.cpp @@ -1,201 +1,215 @@ -#include "ErrorList.h" - -#include "../ServerConfig.h" - -//#include "Poco/Net/MailMessage.h" -#include "Poco/Net/MediaType.h" - -#include "../SingletonManager/EmailManager.h" - -SendErrorMessage::~SendErrorMessage() -{ - if (mMessage) { - delete mMessage; - mMessage = nullptr; - } -} - -int SendErrorMessage::run() -{ - if (ServerConfig::g_disableEmail) return 0; - - auto mailClientSession = new Poco::Net::SecureSMTPClientSession(ServerConfig::g_EmailAccount.url, ServerConfig::g_EmailAccount.port); - mailClientSession->login(); - mailClientSession->startTLS(ServerConfig::g_SSL_CLient_Context); - - - mailClientSession->login(Poco::Net::SMTPClientSession::AUTH_LOGIN, ServerConfig::g_EmailAccount.username, ServerConfig::g_EmailAccount.password); - - try { - mMessage->setSender(ServerConfig::g_EmailAccount.sender); - mailClientSession->sendMessage(*mMessage); - mailClientSession->close(); - } - catch (Poco::Exception& exc) { - printf("[SendErrorMessage::%s] error sending error message to admin: %s\n", - __FUNCTION__, exc.displayText().data()); - return -1; - } - return 0; -} - -// ------------------------------------------------------------------------------------ - - -ErrorList::ErrorList() - : mLogging(Poco::Logger::get("errorLog")) -{ - -} - -ErrorList::~ErrorList() -{ - while (mErrorStack.size() > 0) { - delete mErrorStack.top(); - mErrorStack.pop(); - } -} - -void ErrorList::addError(Error* error, bool log/* = true */) -{ - - if (log) { - std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); - mLogging.error("%s [ErrorList::addError] %s", dateTimeString, error->getString(false)); - - } - mErrorStack.push(error); -} - -Error* ErrorList::getLastError() -{ - if (mErrorStack.size() == 0) { - return nullptr; - } - - Error* error = mErrorStack.top(); - if (error) { - mErrorStack.pop(); - } - - return error; -} - -void ErrorList::clearErrors() -{ - while (mErrorStack.size()) { - auto error = mErrorStack.top(); - if (error) { - delete error; - } - mErrorStack.pop(); - } -} - - -int ErrorList::getErrors(ErrorList* send) -{ - Error* error = nullptr; - int iCount = 0; - while (error = send->getLastError()) { - addError(error, false); - iCount++; - } - return iCount; -} - -void ErrorList::printErrors() -{ - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - printf(error->getString().data()); - delete error; - } -} - -std::vector ErrorList::getErrorsArray() -{ - std::vector result; - result.reserve(mErrorStack.size()); - - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - //result->add(error->getString()); - result.push_back(error->getString()); - delete error; - } - return result; -} - -std::string ErrorList::getErrorsHtml() -{ - std::string res; - res = "
    "; - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - res += "
  • "; - res += error->getHtmlString(); - res += "
  • "; - delete error; - } - res += "
"; - return res; -} - -std::string ErrorList::getErrorsHtmlNewFormat() -{ - std::string html; - - while (mErrorStack.size() > 0) { - auto error = std::unique_ptr(mErrorStack.top()); - mErrorStack.pop(); - html += "
"; - html += "report_problem"; - html += ""; - html += error->getHtmlString(); - html += ""; - html += "
"; - } - return html; -} -/* - -*/ - - -void ErrorList::sendErrorsAsEmail(std::string rawHtml/* = ""*/) -{ - auto em = EmailManager::getInstance(); - /*auto message = new Poco::Net::MailMessage(); - message->setSender("gradido_loginServer@gradido.net"); - message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, "***REMOVED***")); - message->setSubject("Error from Gradido Login Server"); - */ - std::string content; - while (mErrorStack.size() > 0) { - auto error = mErrorStack.top(); - mErrorStack.pop(); - content += error->getString(); - delete error; - } - auto email = new model::Email(content, model::EMAIL_ERROR); - - //message->addContent(new Poco::Net::StringPartSource(content)); - if (rawHtml != "") { - Poco::Net::MediaType mt("text", "html"); - mt.setParameter("charset", "utf-8"); - - email->addContent(new Poco::Net::StringPartSource(rawHtml, mt.toString())); - } - em->addEmail(email); - - //UniLib::controller::TaskPtr sendErrorMessageTask(new SendErrorMessage(message, ServerConfig::g_CPUScheduler)); - //sendErrorMessageTask->scheduleTask(sendErrorMessageTask); - +#include "NotificationList.h" + +#include "../ServerConfig.h" + +//#include "Poco/Net/MailMessage.h" +#include "Poco/Net/MediaType.h" + +#include "../SingletonManager/EmailManager.h" + +SendErrorMessage::~SendErrorMessage() +{ + if (mMessage) { + delete mMessage; + mMessage = nullptr; + } +} + +int SendErrorMessage::run() +{ + if (ServerConfig::g_disableEmail) return 0; + + auto mailClientSession = new Poco::Net::SecureSMTPClientSession(ServerConfig::g_EmailAccount.url, ServerConfig::g_EmailAccount.port); + mailClientSession->login(); + mailClientSession->startTLS(ServerConfig::g_SSL_CLient_Context); + + + mailClientSession->login(Poco::Net::SMTPClientSession::AUTH_LOGIN, ServerConfig::g_EmailAccount.username, ServerConfig::g_EmailAccount.password); + + try { + mMessage->setSender(ServerConfig::g_EmailAccount.sender); + mailClientSession->sendMessage(*mMessage); + mailClientSession->close(); + } + catch (Poco::Exception& exc) { + printf("[SendErrorMessage::%s] error sending error message to admin: %s\n", + __FUNCTION__, exc.displayText().data()); + return -1; + } + return 0; +} + +// ------------------------------------------------------------------------------------ + + +NotificationList::NotificationList() + : mLogging(Poco::Logger::get("errorLog")) +{ + +} + +NotificationList::~NotificationList() +{ + while (mErrorStack.size() > 0) { + delete mErrorStack.top(); + mErrorStack.pop(); + } +} + +void NotificationList::addError(Notification* error, bool log/* = true */) +{ + + if (log) { + std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); + mLogging.error("%s [ErrorList::addError] %s", dateTimeString, error->getString(false)); + + } + mErrorStack.push(error); +} + +void NotificationList::addNotification(Notification* notification) +{ + mErrorStack.push(notification); +} + +Notification* NotificationList::getLastError() +{ + if (mErrorStack.size() == 0) { + return nullptr; + } + + Notification* error = mErrorStack.top(); + if (error) { + mErrorStack.pop(); + } + + return error; +} + +void NotificationList::clearErrors() +{ + while (mErrorStack.size()) { + auto error = mErrorStack.top(); + if (error) { + delete error; + } + mErrorStack.pop(); + } +} + + +int NotificationList::getErrors(NotificationList* send) +{ + Notification* error = nullptr; + int iCount = 0; + while (error = send->getLastError()) { + addError(error, false); + iCount++; + } + return iCount; +} + +void NotificationList::printErrors() +{ + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + printf(error->getString().data()); + delete error; + } +} + +std::vector NotificationList::getErrorsArray() +{ + std::vector result; + result.reserve(mErrorStack.size()); + + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + //result->add(error->getString()); + result.push_back(error->getString()); + delete error; + } + return result; +} + +std::string NotificationList::getErrorsHtml() +{ + std::string res; + res = "
    "; + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + if (error->isError()) { + res += "
  • "; + } + else if (error->isSuccess()) { + res += "
  • "; + } + res += error->getHtmlString(); + res += "
  • "; + delete error; + } + res += "
"; + return res; +} + +std::string NotificationList::getErrorsHtmlNewFormat() +{ + std::string html; + + while (mErrorStack.size() > 0) { + auto error = std::unique_ptr(mErrorStack.top()); + mErrorStack.pop(); + if (error->isError()) { + html += "
"; + html += "report_problem"; + } + else if (error->isSuccess()) { + html += "
"; + } + html += ""; + html += error->getHtmlString(); + html += ""; + html += "
"; + } + return html; +} +/* + +*/ + + +void NotificationList::sendErrorsAsEmail(std::string rawHtml/* = ""*/) +{ + auto em = EmailManager::getInstance(); + /*auto message = new Poco::Net::MailMessage(); + message->setSender("gradido_loginServer@gradido.net"); + message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, "***REMOVED***")); + message->setSubject("Error from Gradido Login Server"); + */ + std::string content; + while (mErrorStack.size() > 0) { + auto error = mErrorStack.top(); + mErrorStack.pop(); + content += error->getString(); + delete error; + } + auto email = new model::Email(content, model::EMAIL_ERROR); + + //message->addContent(new Poco::Net::StringPartSource(content)); + if (rawHtml != "") { + Poco::Net::MediaType mt("text", "html"); + mt.setParameter("charset", "utf-8"); + + email->addContent(new Poco::Net::StringPartSource(rawHtml, mt.toString())); + } + em->addEmail(email); + + //UniLib::controller::TaskPtr sendErrorMessageTask(new SendErrorMessage(message, ServerConfig::g_CPUScheduler)); + //sendErrorMessageTask->scheduleTask(sendErrorMessageTask); } \ No newline at end of file diff --git a/src/cpp/lib/ErrorList.h b/src/cpp/lib/NotificationList.h similarity index 74% rename from src/cpp/lib/ErrorList.h rename to src/cpp/lib/NotificationList.h index d2913a241..a3b2edcf1 100644 --- a/src/cpp/lib/ErrorList.h +++ b/src/cpp/lib/NotificationList.h @@ -1,76 +1,74 @@ -/*! -* -* \author: einhornimmond -* -* \date: 07.03.19 -* -* \brief: error -*/ - -#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H -#define DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H - -#include "Error.h" -#include - -#include "../tasks/CPUTask.h" - -#include "Poco/Net/SecureSMTPClientSession.h" -#include "Poco/Net/StringPartSource.h" -#include "Poco/Logger.h" -#include "Poco/JSON/Array.h" - -class ErrorList : public IErrorCollection -{ -public: - ErrorList(); - ~ErrorList(); - - // push error, error will be deleted in deconstructor - virtual void addError(Error* error, bool log = true); - - // return error on top of stack, please delete after using - Error* getLastError(); - - inline size_t errorCount() { return mErrorStack.size(); } - - // delete all errors - void clearErrors(); - - static int moveErrors(ErrorList* recv, ErrorList* send) { - return recv->getErrors(send); - } - int getErrors(ErrorList* send); - - void printErrors(); - std::string getErrorsHtml(); - std::string getErrorsHtmlNewFormat(); - - std::vector getErrorsArray(); - - void sendErrorsAsEmail(std::string rawHtml = ""); - -protected: - std::stack mErrorStack; - // poco logging - Poco::Logger& mLogging; -}; - -class SendErrorMessage : public UniLib::controller::CPUTask -{ -public: - SendErrorMessage(Poco::Net::MailMessage* message, UniLib::controller::CPUSheduler* scheduler) - : UniLib::controller::CPUTask(scheduler), mMessage(message) {} - - ~SendErrorMessage(); - - virtual int run(); - const char* getResourceType() const { return "SendErrorMessage"; }; - - -protected: - Poco::Net::MailMessage* mMessage; - -}; - -#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H +/*! +* +* \author: einhornimmond +* +* \date: 07.03.19 +* +* \brief: error +*/ + +#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H +#define DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H + +#include "Error.h" +#include + +#include "../tasks/CPUTask.h" + +#include "Poco/Net/SecureSMTPClientSession.h" +#include "Poco/Net/StringPartSource.h" +#include "Poco/Logger.h" + +class NotificationList : public INotificationCollection +{ +public: + NotificationList(); + ~NotificationList(); + + // push error, error will be deleted in deconstructor + virtual void addError(Notification* error, bool log = true); + void addNotification(Notification* notification); + + // return error on top of stack, please delete after using + Notification* getLastError(); + + inline size_t errorCount() { return mErrorStack.size(); } + + // delete all errors + void clearErrors(); + + static int moveErrors(NotificationList* recv, NotificationList* send) { + return recv->getErrors(send); + } + int getErrors(NotificationList* send); + + void printErrors(); + std::string getErrorsHtml(); + std::string getErrorsHtmlNewFormat(); + + void sendErrorsAsEmail(std::string rawHtml = ""); + +protected: + std::stack mErrorStack; + // poco logging + Poco::Logger& mLogging; +}; + +class SendErrorMessage : public UniLib::controller::CPUTask +{ +public: + SendErrorMessage(Poco::Net::MailMessage* message, UniLib::controller::CPUSheduler* scheduler) + : UniLib::controller::CPUTask(scheduler), mMessage(message) {} + + ~SendErrorMessage(); + + virtual int run(); + const char* getResourceType() const { return "SendErrorMessage"; }; + + +protected: + Poco::Net::MailMessage* mMessage; + +}; + +#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H diff --git a/src/cpp/lib/Success.cpp b/src/cpp/lib/Success.cpp new file mode 100644 index 000000000..5cf23f3b8 --- /dev/null +++ b/src/cpp/lib/Success.cpp @@ -0,0 +1,52 @@ +#include "Success.h" +#include + +Success::Success(const char* functionName, const char* message) + : Notification(functionName, message) +{ + +} + +std::string Success::getString(bool withNewline/* = true*/) const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage; + if (withNewline) ss << std::endl; + + return ss.str(); +} +std::string Success::getHtmlString() const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage; + + return ss.str(); +} + +ParamSuccess::ParamSuccess(const char* functionName, const char* message, std::string param) + : Success(functionName, message), mParam(param) +{ + +} + +ParamSuccess::ParamSuccess(const char* functionName, const char* message, int param) + : Success(functionName, message), mParam(std::to_string(param)) +{ + +} + +std::string ParamSuccess::getString(bool withNewline/* = true*/) const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage << " " << mParam; + if (withNewline) ss << std::endl; + + return ss.str(); +} +std::string ParamSuccess::getHtmlString() const +{ + std::stringstream ss; + ss << mFunctionName << ": " << mMessage << " " << mParam; + + return ss.str(); +} \ No newline at end of file diff --git a/src/cpp/lib/Success.h b/src/cpp/lib/Success.h new file mode 100644 index 000000000..4fc4b4fcf --- /dev/null +++ b/src/cpp/lib/Success.h @@ -0,0 +1,30 @@ +#ifndef GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H +#define GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H + +#include "Notification.h" + +class Success : public Notification +{ +public: + Success(const char* functionName, const char* message); + + std::string getString(bool withNewline = true) const; + std::string getHtmlString() const; + + virtual bool isSuccess() { return true; } +}; + +class ParamSuccess : public Success +{ +public: + ParamSuccess(const char* functionName, const char* message, std::string param); + ParamSuccess(const char* functionName, const char* message, int param); + + std::string getString(bool withNewline = true) const; + std::string getHtmlString() const; + +protected: + std::string mParam; +}; + +#endif //GRADIDO_LOGIN_SERVER_LIB_SUCCESS_H \ No newline at end of file diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index ec60b6fc3..b8f2cc949 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -1,282 +1,281 @@ -/*! -* -* \author: einhornimmond -* -* \date: 02.03.19 -* -* \brief: store session data -*/ - -#ifndef DR_LUA_WEB_MODULE_SESSION_SESSION_H -#define DR_LUA_WEB_MODULE_SESSION_SESSION_H - -#include "../lib/ErrorList.h" -#include "User.h" -#include "../controller/User.h" - -#include "../lib/MultithreadContainer.h" -#include "../tasks/ProcessingTransaction.h" - -#include "../SingletonManager/LanguageManager.h" - -#include "../controller/EmailVerificationCode.h" - -#include "Poco/Thread.h" -#include "Poco/Types.h" -#include "Poco/DateTime.h" -#include "Poco/Net/IPAddress.h" -#include "Poco/Net/HTTPCookie.h" - -#include - - -class WriteEmailVerification; - -enum SessionStates { - SESSION_STATE_EMPTY, - SESSION_STATE_CRYPTO_KEY_GENERATED, - SESSION_STATE_USER_WRITTEN, - SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, - SESSION_STATE_EMAIL_VERIFICATION_SEND, - SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED, - SESSION_STATE_PASSPHRASE_GENERATED, - SESSION_STATE_PASSPHRASE_SHOWN, - SESSION_STATE_PASSPHRASE_WRITTEN, - SESSION_STATE_KEY_PAIR_GENERATED, - SESSION_STATE_KEY_PAIR_WRITTEN, - SESSION_STATE_RESET_PASSWORD_REQUEST, - SESSION_STATE_RESET_PASSWORD_SUCCEED, - SESSION_STATE_COUNT -}; - -class SessionManager; - -class UpdateUserPasswordPage; -class PassphrasePage; -class RepairDefectPassphrase; - -class Session : public ErrorList, public UniLib::lib::MultithreadContainer -{ - friend WriteEmailVerification; - friend SessionManager; - friend UpdateUserPasswordPage; - friend PassphrasePage; - friend RepairDefectPassphrase; -public: - Session(int handle); - ~Session(); - - // get new model objects - Poco::AutoPtr getEmailVerificationCodeObject(); - - // set new model objects - inline void setUser(Poco::AutoPtr user) { mNewUser = user; } - inline Poco::AutoPtr getNewUser() { return mNewUser; } - - // ---------------- User functions ---------------------------- - // TODO: register state: written into db, mails sended, update state only if new state is higher as old state - // create User send e-mail activation link - bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); - - //! \brief new register function, without showing user pubkeys, using controller/user - bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); - - - // adminRegister without passwort - bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); - - // TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing - UserStates loadUser(const std::string& email, const std::string& password); - bool ifUserExist(const std::string& email); - - inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } - - - bool deleteUser(); - - Poco::AutoPtr getUser() { - return mSessionUser; - } - - // ------------------------- Email Verification Code functions ------------------------------- - - bool loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode); - - //! \return 1 = konto already exist - //! -1 = invalid code - //! -2 = critical error - //! 0 = ok - int updateEmailVerification(Poco::UInt64 emailVerificationCode); - - // called from page with same name - //! \return 1 = reset password email already send - //! \return 2 = reset password email already shortly before - //! \return 0 = ok - int sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized); - // - //! \return 0 = not the same - //! \return 1 = same - //! \return -1 = error - //! \return -2 = critical error - int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource); - - Poco::Net::HTTPCookie getLoginCookie(); - - - inline int getHandle() { return mHandleId; } - - // ------------------------ Passphrase functions ---------------------------- - - inline void setPassphrase(Poco::AutoPtr passphrase) { mNewPassphrase = passphrase; } - inline Poco::AutoPtr getPassphrase() { return mNewPassphrase; } - - inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; } - - inline const std::string& getOldPassphrase() { return mPassphrase; } - bool generatePassphrase(); - bool generateKeys(bool savePrivkey, bool savePassphrase); - - inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; } - inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; } - - inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; } - bool isPwdValid(const std::string& pwd); - void reset(); - - void updateState(SessionStates newState); - const char* getSessionStateString(); - inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; } - - inline Poco::UInt64 getEmailVerificationCode() { - std::shared_lock _lock(mSharedMutex); - if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode(); - } - inline void setEmailVerificationCodeObject(Poco::AutoPtr emailVerficationObject) { - std::unique_lock _lock(mSharedMutex); - mEmailVerificationCodeObject = emailVerficationObject; - } - inline model::table::EmailOptInType getEmailVerificationType() { - std::shared_lock _lock(mSharedMutex); - if (mEmailVerificationCodeObject.isNull()) { - return model::table::EMAIL_OPT_IN_EMPTY; - } - return mEmailVerificationCodeObject->getModel()->getType(); - } - - //! \return -1 if session is locked - //! \return 1 if session is active - //! \return 0 - int isActive(); - //! \return false if session is locked - bool setActive(bool active); - - bool isDeadLocked(); - - inline Poco::DateTime getLastActivity() { return mLastActivity; } - - // ------------------------ transactions functions ---------------------------- - - //! \return true if succeed - bool startProcessingTransaction(const std::string& proto_message_base64, bool autoSign = false); - //! \param working if set will filled with transaction running - Poco::AutoPtr getNextReadyTransaction(size_t* working = nullptr); - bool finalizeTransaction(bool sign, bool reject); - size_t getProcessingTransactionCount(); - - inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; } - void setLanguage(Languages lang); - inline void setLanguageCatalog(Poco::AutoPtr languageCatalog) { mLanguageCatalog = languageCatalog; } - Languages getLanguage(); - inline const char* gettext(const char* text) { if (mLanguageCatalog.isNull()) return text; return mLanguageCatalog->gettext(text); } - - // last referer - inline void setLastReferer(const std::string& lastReferer) { mLastExternReferer = lastReferer; } - inline const std::string& getLastReferer() const { return mLastExternReferer; } - -protected: - void updateTimeout(); - inline void setHandle(int newHandle) { mHandleId = newHandle; } - - void detectSessionState(); - static const char* translateSessionStateToString(SessionStates state); - - inline const std::string& getPassphrase() const { return mPassphrase; } - - -private: - int mHandleId; - Poco::AutoPtr mSessionUser; - Poco::AutoPtr mNewUser; - std::string mPassphrase; - Poco::AutoPtr mNewPassphrase; - Poco::DateTime mLastActivity; - Poco::Net::IPAddress mClientLoginIP; - std::string mLastExternReferer; - Poco::AutoPtr mEmailVerificationCodeObject; - std::shared_mutex mSharedMutex; - - - SessionStates mState; - - bool mActive; - std::list> mProcessingTransactions; - Poco::AutoPtr mCurrentActiveProcessingTransaction; - - Poco::AutoPtr mLanguageCatalog; -}; - - -class WriteEmailVerification : public UniLib::controller::CPUTask -{ -public: - WriteEmailVerification(Poco::AutoPtr user, Poco::AutoPtr emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) - : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) { -#ifdef _UNI_LIB_DEBUG - setName(user->getEmail()); -#endif - } - - virtual const char* getResourceType() const { return "WriteEmailVerification"; }; - virtual int run(); - -private: - Poco::AutoPtr mUser; - Poco::AutoPtr mEmailVerificationCode; - -}; - -class WritePassphraseIntoDB : public UniLib::controller::CPUTask -{ -public: - WritePassphraseIntoDB(int userId, const std::string& passphrase) - : mUserId(userId), mPassphrase(passphrase) { -#ifdef _UNI_LIB_DEBUG - setName(std::to_string(userId).data()); -#endif - } - - - virtual int run(); - virtual const char* getResourceType() const { return "WritePassphraseIntoDB"; }; - -protected: - int mUserId; - std::string mPassphrase; -}; - -class SessionStateUpdateCommand : public UniLib::controller::Command -{ -public: - SessionStateUpdateCommand(SessionStates state, Session* session) - : mState(state), mSession(session) {} - virtual int taskFinished(UniLib::controller::Task* task) { - mSession->updateState(mState); - return 0; - } - -protected: - SessionStates mState; - Session* mSession; -}; - -#endif // DR_LUA_WEB_MODULE_SESSION_SESSION_H +/*! +* +* \author: einhornimmond +* +* \date: 02.03.19 +* +* \brief: store session data +*/ + +#ifndef DR_LUA_WEB_MODULE_SESSION_SESSION_H +#define DR_LUA_WEB_MODULE_SESSION_SESSION_H + +#include "../lib/NotificationList.h" +#include "User.h" +#include "../controller/User.h" + +#include "../lib/MultithreadContainer.h" +#include "../tasks/ProcessingTransaction.h" + +#include "../SingletonManager/LanguageManager.h" + +#include "../controller/EmailVerificationCode.h" + +#include "Poco/Thread.h" +#include "Poco/Types.h" +#include "Poco/DateTime.h" +#include "Poco/Net/IPAddress.h" +#include "Poco/Net/HTTPCookie.h" + +#include + + +class WriteEmailVerification; + +enum SessionStates { + SESSION_STATE_EMPTY, + SESSION_STATE_CRYPTO_KEY_GENERATED, + SESSION_STATE_USER_WRITTEN, + SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, + SESSION_STATE_EMAIL_VERIFICATION_SEND, + SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED, + SESSION_STATE_PASSPHRASE_GENERATED, + SESSION_STATE_PASSPHRASE_SHOWN, + SESSION_STATE_PASSPHRASE_WRITTEN, + SESSION_STATE_KEY_PAIR_GENERATED, + SESSION_STATE_KEY_PAIR_WRITTEN, + SESSION_STATE_RESET_PASSWORD_REQUEST, + SESSION_STATE_RESET_PASSWORD_SUCCEED, + SESSION_STATE_COUNT +}; + +class SessionManager; +class UpdateUserPasswordPage; +class PassphrasePage; +class RepairDefectPassphrase; + +class Session : public NotificationList, public UniLib::lib::MultithreadContainer +{ + friend WriteEmailVerification; + friend SessionManager; + friend UpdateUserPasswordPage; + friend PassphrasePage; + friend RepairDefectPassphrase; +public: + Session(int handle); + ~Session(); + + // get new model objects + Poco::AutoPtr getEmailVerificationCodeObject(); + + // set new model objects + inline void setUser(Poco::AutoPtr user) { mNewUser = user; } + inline Poco::AutoPtr getNewUser() { return mNewUser; } + + // ---------------- User functions ---------------------------- + // TODO: register state: written into db, mails sended, update state only if new state is higher as old state + // create User send e-mail activation link + bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + + //! \brief new register function, without showing user pubkeys, using controller/user + bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + + + // adminRegister without passwort + bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); + + // TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing + UserStates loadUser(const std::string& email, const std::string& password); + bool ifUserExist(const std::string& email); + + inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } + + + bool deleteUser(); + + Poco::AutoPtr getUser() { + return mSessionUser; + } + + // ------------------------- Email Verification Code functions ------------------------------- + + bool loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode); + + //! \return 1 = konto already exist + //! -1 = invalid code + //! -2 = critical error + //! 0 = ok + int updateEmailVerification(Poco::UInt64 emailVerificationCode); + + // called from page with same name + //! \return 1 = reset password email already send + //! \return 2 = reset password email already shortly before + //! \return 0 = ok + int sendResetPasswordEmail(Poco::AutoPtr user, bool passphraseMemorized); + // + //! \return 0 = not the same + //! \return 1 = same + //! \return -1 = error + //! \return -2 = critical error + int comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource); + + Poco::Net::HTTPCookie getLoginCookie(); + + + inline int getHandle() { return mHandleId; } + + // ------------------------ Passphrase functions ---------------------------- + + inline void setPassphrase(Poco::AutoPtr passphrase) { mNewPassphrase = passphrase; } + inline Poco::AutoPtr getPassphrase() { return mNewPassphrase; } + + inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; } + + inline const std::string& getOldPassphrase() { return mPassphrase; } + bool generatePassphrase(); + bool generateKeys(bool savePrivkey, bool savePassphrase); + + inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; } + inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; } + + inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; } + bool isPwdValid(const std::string& pwd); + void reset(); + + void updateState(SessionStates newState); + const char* getSessionStateString(); + inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; } + + inline Poco::UInt64 getEmailVerificationCode() { + std::shared_lock _lock(mSharedMutex); + if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode(); + } + inline void setEmailVerificationCodeObject(Poco::AutoPtr emailVerficationObject) { + std::unique_lock _lock(mSharedMutex); + mEmailVerificationCodeObject = emailVerficationObject; + } + inline model::table::EmailOptInType getEmailVerificationType() { + std::shared_lock _lock(mSharedMutex); + if (mEmailVerificationCodeObject.isNull()) { + return model::table::EMAIL_OPT_IN_EMPTY; + } + return mEmailVerificationCodeObject->getModel()->getType(); + } + + //! \return -1 if session is locked + //! \return 1 if session is active + //! \return 0 + int isActive(); + //! \return false if session is locked + bool setActive(bool active); + + bool isDeadLocked(); + + inline Poco::DateTime getLastActivity() { return mLastActivity; } + + // ------------------------ transactions functions ---------------------------- + + //! \return true if succeed + bool startProcessingTransaction(const std::string& proto_message_base64, bool autoSign = false); + //! \param working if set will filled with transaction running + Poco::AutoPtr getNextReadyTransaction(size_t* working = nullptr); + bool finalizeTransaction(bool sign, bool reject); + size_t getProcessingTransactionCount(); + + inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; } + void setLanguage(Languages lang); + inline void setLanguageCatalog(Poco::AutoPtr languageCatalog) { mLanguageCatalog = languageCatalog; } + Languages getLanguage(); + inline const char* gettext(const char* text) { if (mLanguageCatalog.isNull()) return text; return mLanguageCatalog->gettext(text); } + + // last referer + inline void setLastReferer(const std::string& lastReferer) { mLastExternReferer = lastReferer; } + inline const std::string& getLastReferer() const { return mLastExternReferer; } + +protected: + void updateTimeout(); + inline void setHandle(int newHandle) { mHandleId = newHandle; } + + void detectSessionState(); + static const char* translateSessionStateToString(SessionStates state); + + inline const std::string& getPassphrase() const { return mPassphrase; } + + +private: + int mHandleId; + Poco::AutoPtr mSessionUser; + Poco::AutoPtr mNewUser; + std::string mPassphrase; + Poco::AutoPtr mNewPassphrase; + Poco::DateTime mLastActivity; + Poco::Net::IPAddress mClientLoginIP; + std::string mLastExternReferer; + Poco::AutoPtr mEmailVerificationCodeObject; + std::shared_mutex mSharedMutex; + + + SessionStates mState; + + bool mActive; + std::list> mProcessingTransactions; + Poco::AutoPtr mCurrentActiveProcessingTransaction; + + Poco::AutoPtr mLanguageCatalog; +}; + + +class WriteEmailVerification : public UniLib::controller::CPUTask +{ +public: + WriteEmailVerification(Poco::AutoPtr user, Poco::AutoPtr emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) + : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) { +#ifdef _UNI_LIB_DEBUG + setName(user->getEmail()); +#endif + } + + virtual const char* getResourceType() const { return "WriteEmailVerification"; }; + virtual int run(); + +private: + Poco::AutoPtr mUser; + Poco::AutoPtr mEmailVerificationCode; + +}; + +class WritePassphraseIntoDB : public UniLib::controller::CPUTask +{ +public: + WritePassphraseIntoDB(int userId, const std::string& passphrase) + : mUserId(userId), mPassphrase(passphrase) { +#ifdef _UNI_LIB_DEBUG + setName(std::to_string(userId).data()); +#endif + } + + + virtual int run(); + virtual const char* getResourceType() const { return "WritePassphraseIntoDB"; }; + +protected: + int mUserId; + std::string mPassphrase; +}; + +class SessionStateUpdateCommand : public UniLib::controller::Command +{ +public: + SessionStateUpdateCommand(SessionStates state, Session* session) + : mState(state), mSession(session) {} + virtual int taskFinished(UniLib::controller::Task* task) { + mSession->updateState(mState); + return 0; + } + +protected: + SessionStates mState; + Session* mSession; +}; + +#endif // DR_LUA_WEB_MODULE_SESSION_SESSION_H diff --git a/src/cpp/model/TransactionBase.h b/src/cpp/model/TransactionBase.h index 84406fddb..5bb0bad14 100644 --- a/src/cpp/model/TransactionBase.h +++ b/src/cpp/model/TransactionBase.h @@ -11,11 +11,11 @@ #pragma warning(disable:4800) -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../proto/gradido/BasicTypes.pb.h" #include "../SingletonManager/MemoryManager.h" -class TransactionBase : public ErrorList, public UniLib::lib::MultithreadContainer +class TransactionBase : public NotificationList, public UniLib::lib::MultithreadContainer { public: TransactionBase(const std::string& memo); diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index 80763d337..a57324cf8 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -732,7 +732,7 @@ void User::setEmailChecked() unlock(); } -bool User::validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint) +bool User::validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint) { auto mm = MemoryManager::getInstance(); auto cmpCryptoKey = createCryptoKey(pwd); @@ -935,7 +935,7 @@ MemoryBin* User::createCryptoKey(const std::string& password) return key; } -User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver/* = nullptr*/) +User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver/* = nullptr*/) { if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) { throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)"); diff --git a/src/cpp/model/User.h b/src/cpp/model/User.h index c041cea7d..cc1a8be86 100644 --- a/src/cpp/model/User.h +++ b/src/cpp/model/User.h @@ -4,7 +4,7 @@ #include "../Crypto/KeyPair.h" #include //#include "ModelBase.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "Poco/Thread.h" #include "Poco/Types.h" @@ -50,7 +50,7 @@ enum UserFields USER_FIELDS_LANGUAGE }; -class User : public ErrorList +class User : public NotificationList { friend UserCreateCryptoKey; friend UserWriteIntoDB; @@ -115,7 +115,7 @@ public: bool isEmptyPassword(); //bool setNewPassword(const std::string& newPassword); bool updatePassword(const std::string& newPassword, const std::string& passphrase, Poco::AutoPtr newUser); - bool validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint); + bool validatePwd(const std::string& pwd, NotificationList* validationErrorsToPrint); bool validateIdentHash(HASH hash); MemoryBin* encrypt(const MemoryBin* data); @@ -134,7 +134,7 @@ protected: typedef Poco::UInt64 passwordHashed; MemoryBin* createCryptoKey(const std::string& password); - static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver = nullptr); + static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, NotificationList* errorReceiver = nullptr); inline void setCryptoKey(MemoryBin* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); } //void detectState(); diff --git a/src/cpp/model/email/Email.h b/src/cpp/model/email/Email.h index d2887a26c..0fc52cac0 100644 --- a/src/cpp/model/email/Email.h +++ b/src/cpp/model/email/Email.h @@ -17,7 +17,7 @@ #include "../../SingletonManager/LanguageManager.h" -#include "../../lib/ErrorList.h" +#include "../../lib/NotificationList.h" namespace model { using namespace Poco; @@ -39,7 +39,7 @@ namespace model { EMAIL_MAX }; - class Email: public ErrorList + class Email: public NotificationList { public: Email(AutoPtr emailVerification, AutoPtr user, EmailType type); diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.cpp b/src/cpp/model/hedera/CryptoTransferTransaction.cpp new file mode 100644 index 000000000..828a85645 --- /dev/null +++ b/src/cpp/model/hedera/CryptoTransferTransaction.cpp @@ -0,0 +1,53 @@ +#include "CryptoTransferTransaction.h" + +namespace model { + namespace hedera { + + CryptoTransferTransaction::CryptoTransferTransaction() + : mCryptoTransfer(nullptr) + { + mCryptoTransfer = new proto::CryptoTransferTransactionBody; + } + + CryptoTransferTransaction::~CryptoTransferTransaction() + { + if (mCryptoTransfer) { + delete mCryptoTransfer; + mCryptoTransfer = nullptr; + } + } + + void CryptoTransferTransaction::addSender(Poco::AutoPtr senderAccountId, Poco::UInt64 amountTinybars) + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto accountAmounts = transfers->add_accountamounts(); + accountAmounts->set_amount(-(Poco::Int64)amountTinybars); + senderAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid()); + } + void CryptoTransferTransaction::addReceiver(Poco::AutoPtr receiverAccountId, Poco::UInt64 amountTinybars) + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto accountAmounts = transfers->add_accountamounts(); + accountAmounts->set_amount(amountTinybars); + receiverAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid()); + } + + bool CryptoTransferTransaction::validate() + { + auto transfers = mCryptoTransfer->mutable_transfers(); + auto account_amounts = transfers->accountamounts(); + Poco::Int64 sum = 0; + for (int i = 0; i < transfers->accountamounts_size(); i++) { + auto account_amount = account_amounts.Mutable(i); + sum += account_amount->amount(); + } + return 0 == sum && transfers->accountamounts_size() > 0; + } + + void CryptoTransferTransaction::resetPointer() + { + mCryptoTransfer = nullptr; + } + } +} + diff --git a/src/cpp/model/hedera/CryptoTransferTransaction.h b/src/cpp/model/hedera/CryptoTransferTransaction.h new file mode 100644 index 000000000..04aacafea --- /dev/null +++ b/src/cpp/model/hedera/CryptoTransferTransaction.h @@ -0,0 +1,40 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for creating a hedera transfer transaction +* +*/ + +#include "../../proto/hedera/CryptoTransfer.pb.h" +#include "../../controller/HederaId.h" + +namespace model { + namespace hedera { + class CryptoTransferTransaction + { + public: + CryptoTransferTransaction(); + ~CryptoTransferTransaction(); + + void addSender(Poco::AutoPtr senderAccountId, Poco::UInt64 amountTinybars); + void addReceiver(Poco::AutoPtr receiverAccountId, Poco::UInt64 amountTinybars); + + bool validate(); + // set pointer to zero, after hand over pointer to transaction body + void resetPointer(); + + inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; } + + protected: + proto::CryptoTransferTransactionBody* mCryptoTransfer; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index 39b3700c4..de4fdec99 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -2,18 +2,24 @@ #include "Poco/Timestamp.h" #include "../../SingletonManager/MemoryManager.h" +#include "Transaction.h" +#include "TransactionBody.h" +#include "CryptoTransferTransaction.h" + namespace model { namespace hedera { Query::Query(const controller::NodeServerConnection& connection) - : mConnection(connection) + : mConnection(connection), mTransactionBody(nullptr) { } Query::~Query() { - + if (mTransactionBody) { + delete mTransactionBody; + } } Query* Query::getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection) @@ -26,58 +32,46 @@ namespace model { accountId->copyToProtoAccountId(get_account_balance->mutable_accountid()); auto query_header = get_account_balance->mutable_header(); query_header->set_responsetype(proto::COST_ANSWER); - auto transaction = query_header->mutable_payment(); + + query->mTransactionBody = new TransactionBody(accountId, connection); + CryptoTransferTransaction crypto_transaction; + crypto_transaction.addSender(accountId, 0); + crypto_transaction.addReceiver(connection.hederaId, 0); + query->mTransactionBody->setCryptoTransfer(crypto_transaction); + + //auto transaction = query_header->mutable_payment(); //auto transaction_body = transaction->mutable_body(); // body content - // transaction id - auto transaction_id = query->mTransactionBody.mutable_transactionid(); - auto timestamp = transaction_id->mutable_transactionvalidstart(); - Poco::Timestamp now; - auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 - timestamp->set_seconds(now.epochTime()); - timestamp->set_nanos(microseconds * 1000); - accountId->copyToProtoAccountId(transaction_id->mutable_accountid()); - // - // sdk default, but can be changed - query->mTransactionBody.set_transactionfee(100000000); - auto valid_duration = query->mTransactionBody.mutable_transactionvalidduration(); - // maximal 2 minutes - valid_duration->set_seconds(120); - auto crypto_transfer = query->mTransactionBody.mutable_cryptotransfer(); - auto transfer_list = crypto_transfer->mutable_transfers(); - auto account_amounts = transfer_list->mutable_accountamounts(); - account_amounts->Add(); - auto account_amount = account_amounts->Mutable(0); - account_amount->set_amount(1000); - connection.hederaId->copyToProtoAccountId(account_amount->mutable_accountid()); + // node account id + return query; } bool Query::sign(std::unique_ptr keyPairHedera) { - auto mm = MemoryManager::getInstance(); - auto body_bytes = mTransactionBody.SerializeAsString(); - auto transaction = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header()->mutable_payment(); - transaction->set_bodybytes(body_bytes.data()); - auto signature_map = transaction->mutable_sigmap(); - auto signature_pairs = signature_map->mutable_sigpair(); - signature_pairs->Add(); - auto signature_pair = signature_pairs->Mutable(0); - auto public_key = keyPairHedera->getPublicKey(); + Transaction transaction; + auto sign_result = transaction.sign(std::move(keyPairHedera), mTransactionBody); + auto query_header = mQueryProto.mutable_cryptogetaccountbalance()->mutable_header(); + query_header->set_allocated_payment(transaction.getTransaction()); + transaction.resetPointer(); - - auto sign = keyPairHedera->sign(body_bytes); - if (!sign) { - printf("[Query::sign] error signing message\n"); - return false; - } - signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); - signature_pair->set_ed25519(*sign, sign->size()); + return sign_result; + } - mm->releaseMemory(sign); + void Query::setResponseType(proto::ResponseType type) + { + auto get_account_balance = mQueryProto.mutable_cryptogetaccountbalance(); + auto query_header = get_account_balance->mutable_header(); + query_header->set_responsetype(type); - return true; + } + + proto::ResponseType Query::getResponseType() + { + auto get_account_balance = mQueryProto.mutable_cryptogetaccountbalance(); + auto query_header = get_account_balance->mutable_header(); + return query_header->responsetype(); } } } \ No newline at end of file diff --git a/src/cpp/model/hedera/Query.h b/src/cpp/model/hedera/Query.h index ad9af855a..fa9b06471 100644 --- a/src/cpp/model/hedera/Query.h +++ b/src/cpp/model/hedera/Query.h @@ -13,6 +13,7 @@ #include "../../proto/hedera/Query.pb.h" #include "../../controller/NodeServer.h" #include "../../Crypto/KeyPairHedera.h" +#include "TransactionBody.h" namespace model { namespace hedera { @@ -23,13 +24,16 @@ namespace model { static Query* getBalance(Poco::AutoPtr accountId, const controller::NodeServerConnection& connection); bool sign(std::unique_ptr keyPairHedera); + void setResponseType(proto::ResponseType type); + proto::ResponseType getResponseType(); + void setFee(Poco::UInt64 fee); inline const proto::Query* getProtoQuery() const { return &mQueryProto; } inline std::string getConnectionString() const { return mConnection.getUriWithPort(); } protected: Query(const controller::NodeServerConnection& connection); proto::Query mQueryProto; - proto::TransactionBody mTransactionBody; + TransactionBody* mTransactionBody; controller::NodeServerConnection mConnection; }; } diff --git a/src/cpp/model/hedera/Response.cpp b/src/cpp/model/hedera/Response.cpp index e69de29bb..a39c5364e 100644 --- a/src/cpp/model/hedera/Response.cpp +++ b/src/cpp/model/hedera/Response.cpp @@ -0,0 +1,32 @@ +#include "Response.h" + +namespace model { + namespace hedera { + Response::Response() + { + } + + Response::~Response() + { + + } + + Poco::UInt64 Response::getAccountBalance() + { + if (isCryptoGetAccountBalanceResponse()) { + auto balance_response = mResponseProto.cryptogetaccountbalance(); + return balance_response.balance(); + } + return 0; + } + + proto::ResponseCodeEnum Response::getResponseCode() + { + if (isCryptoGetAccountBalanceResponse()) { + auto balance_response = mResponseProto.cryptogetaccountbalance(); + return balance_response.header().nodetransactionprecheckcode(); + } + return proto::NOT_SUPPORTED; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Response.h b/src/cpp/model/hedera/Response.h index e69de29bb..779f5e982 100644 --- a/src/cpp/model/hedera/Response.h +++ b/src/cpp/model/hedera/Response.h @@ -0,0 +1,38 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H + +/*! +* @author: Dario Rekowski +* +* @date: 03.09.20 +* +* @brief: class for simply accessing hedera responses +* +*/ + +#include "../../proto/hedera/Response.pb.h" +#include "Poco/Types.h" + +namespace model { + namespace hedera { + class Response + { + public: + Response(); + ~Response(); + + inline proto::Response* getResponsePtr() { return &mResponseProto; } + Poco::UInt64 getAccountBalance(); + proto::ResponseCodeEnum getResponseCode(); + + inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); } + + protected: + proto::Response mResponseProto; + + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index e69de29bb..0dadbcb4c 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -0,0 +1,43 @@ +#include "Transaction.h" + +namespace model { + namespace hedera { + Transaction::Transaction() + : mTransaction(nullptr) + { + mTransaction = new proto::Transaction; + } + + Transaction::~Transaction() + { + if (mTransaction) { + delete mTransaction; + mTransaction = nullptr; + } + } + + bool Transaction::sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody) + { + auto mm = MemoryManager::getInstance(); + auto transaction_body_proto = transactionBody->getProtoTransactionBody(); + auto body_bytes = transaction_body_proto->SerializeAsString(); + mTransaction->set_bodybytes(body_bytes.data()); + auto signature_map = mTransaction->mutable_sigmap(); + auto signature_pairs = signature_map->mutable_sigpair(); + signature_map->add_sigpair(); + auto signature_pair = signature_pairs->Mutable(0); + auto public_key = keyPairHedera->getPublicKey(); + + auto sign = keyPairHedera->sign(body_bytes); + if (!sign) { + printf("[Query::sign] error signing message\n"); + return false; + } + signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize()); + signature_pair->set_ed25519(*sign, sign->size()); + + mm->releaseMemory(sign); + return true; + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index e69de29bb..3acf46ff9 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -0,0 +1,38 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing hedera transaction +* +*/ + +#include "../../proto/hedera/Transaction.pb.h" +#include "../../Crypto/KeyPairHedera.h" +#include "TransactionBody.h" + +namespace model { + namespace hedera { + class Transaction + { + public: + Transaction(); + ~Transaction(); + + bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); + + inline proto::Transaction* getTransaction() { return mTransaction; } + void resetPointer() { mTransaction = nullptr; } + + protected: + + proto::Transaction* mTransaction; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.cpp b/src/cpp/model/hedera/TransactionBody.cpp index e69de29bb..f1979b6bf 100644 --- a/src/cpp/model/hedera/TransactionBody.cpp +++ b/src/cpp/model/hedera/TransactionBody.cpp @@ -0,0 +1,47 @@ +#include "TransactionBody.h" + +namespace model { + namespace hedera { + TransactionBody::TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection) + { + connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid()); + auto transaction_id = mTransactionBody.mutable_transactionid(); + operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid()); + mTransactionBody.set_transactionfee(10000); + auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration(); + transaction_valid_duration->set_seconds(120); + + updateTimestamp(); + } + + TransactionBody::~TransactionBody() + { + + } + + bool TransactionBody::setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction) + { + if (cryptoTransferTransaction.validate()) { + mTransactionBody.set_allocated_cryptotransfer(cryptoTransferTransaction.getProtoTransactionBody()); + cryptoTransferTransaction.resetPointer(); + return true; + } + return false; + } + + void TransactionBody::setMemo(const std::string& memo) + { + mTransactionBody.set_memo(memo); + } + + void TransactionBody::updateTimestamp() + { + auto transaction_id = mTransactionBody.mutable_transactionid(); + auto timestamp = transaction_id->mutable_transactionvalidstart(); + Poco::Timestamp now; + auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6 + timestamp->set_seconds(now.epochTime()); + timestamp->set_nanos(microseconds * 1000); + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionBody.h b/src/cpp/model/hedera/TransactionBody.h index e69de29bb..3663c4a59 100644 --- a/src/cpp/model/hedera/TransactionBody.h +++ b/src/cpp/model/hedera/TransactionBody.h @@ -0,0 +1,39 @@ +#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H +#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H + +/*! +* @author: Dario Rekowski +* +* @date: 02.09.20 +* +* @brief: class for composing transaction body for hedera transaction +* +*/ + +#include "../../proto/hedera/TransactionBody.pb.h" +#include "../../controller/NodeServer.h" +#include "CryptoTransferTransaction.h" + +namespace model { + namespace hedera { + class TransactionBody + { + public: + TransactionBody(Poco::AutoPtr operatorAccountId, const controller::NodeServerConnection& connection); + ~TransactionBody(); + + void setMemo(const std::string& memo); + + bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction); + + inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; } + + protected: + void updateTimestamp(); + proto::TransactionBody mTransactionBody; + }; + } +} + + +#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H \ No newline at end of file diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 9a1e823fe..62ff4958a 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -24,7 +24,7 @@ namespace model { MYSQL_CONDITION_OR }; - class ModelBase : public UniLib::lib::MultithreadContainer, public ErrorList + class ModelBase : public UniLib::lib::MultithreadContainer, public NotificationList { public: ModelBase(int id) :mID(id), mReferenceCount(1) {} diff --git a/src/cpp/tasks/ProcessingTransaction.h b/src/cpp/tasks/ProcessingTransaction.h index 9886bac8a..269cde176 100644 --- a/src/cpp/tasks/ProcessingTransaction.h +++ b/src/cpp/tasks/ProcessingTransaction.h @@ -3,7 +3,7 @@ #include "CPUTask.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" #include "../lib/DRHash.h" #include "../model/TransactionBase.h" @@ -28,7 +28,7 @@ class TransactionCreation; class TransactionTransfer; class SigningTransaction; -class ProcessingTransaction : public UniLib::controller::CPUTask, public ErrorList +class ProcessingTransaction : public UniLib::controller::CPUTask, public NotificationList { friend SigningTransaction; public: diff --git a/src/cpp/tasks/SigningTransaction.h b/src/cpp/tasks/SigningTransaction.h index 2038c0669..aaedbea0d 100644 --- a/src/cpp/tasks/SigningTransaction.h +++ b/src/cpp/tasks/SigningTransaction.h @@ -1,46 +1,45 @@ -#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(); - -}; - - +#ifndef GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE +#define GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE + +#include "CPUTask.h" + +#include "../lib/NotificationList.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 NotificationList +{ +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; + bool mSendErrorsToAdminEmail; + +private: + + std::string getUserEmail(); + +}; + #endif //GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE \ No newline at end of file diff --git a/src/cpp/tasks/Task.cpp b/src/cpp/tasks/Task.cpp index e75b1a53d..07bb4c3fc 100644 --- a/src/cpp/tasks/Task.cpp +++ b/src/cpp/tasks/Task.cpp @@ -1,5 +1,5 @@ #include "Task.h" -#include "../lib/ErrorList.h" +#include "../lib/NotificationList.h" namespace UniLib { namespace controller { @@ -87,7 +87,7 @@ namespace UniLib { mWorkingMutex.lock(500); } catch (Poco::TimeoutException& ex) { - ErrorList errors; + NotificationList errors; errors.addError(new ParamError("Task::lock", getResourceType(), ex.displayText())); errors.sendErrorsAsEmail(); } diff --git a/src/cpsp/adminHederaAccount.cpsp b/src/cpsp/adminHederaAccount.cpsp index 5379e4ef4..3e8795d24 100644 --- a/src/cpsp/adminHederaAccount.cpsp +++ b/src/cpsp/adminHederaAccount.cpsp @@ -10,6 +10,8 @@ #include "../controller/HederaId.h" #include "../controller/CryptoKey.h" #include "../lib/DataTypeConverter.h" +#include "../lib/Profiler.h" +#include "../lib/Success.h" #include "../SingletonManager/SessionManager.h" #include "../ServerConfig.h" @@ -22,6 +24,8 @@ auto sm = SessionManager::getInstance(); auto mm = MemoryManager::getInstance(); auto user = mSession->getNewUser(); + Profiler hedera_time; + std::string hedera_time_string; Poco::URI uri(request.getURI()); auto uri_query = uri.getQueryParameters(); @@ -44,7 +48,9 @@ if(!hedera_account.size() || hedera_account[0].isNull()) { addError(new Error("Action Update Balance", "hedera id not found")); } else { + hedera_time.reset(); hedera_account[0]->updateBalanceFromHedera(user, this); + addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string())); } } } @@ -148,6 +154,7 @@ %><%@ include file="header_large.cpsp" %> <%= getErrorsHtml() %> +