From feb3067f3af94479d19e3bbe3a6257bcc1bdcb02 Mon Sep 17 00:00:00 2001 From: Dario Date: Thu, 2 Jan 2020 12:47:32 +0100 Subject: [PATCH] adding new email system, work in progress --- files_to_translate.txt | 1 + src/cpp/Gradido_LoginServer.cpp | 3 +- src/cpp/HTTPInterface/ElopageWebhook.cpp | 4 +- src/cpp/ServerConfig.cpp | 2 +- src/cpp/ServerConfig.h | 4 +- src/cpp/SingletonManager/EmailManager.cpp | 61 ++++++ src/cpp/SingletonManager/EmailManager.h | 59 ++++++ src/cpp/SingletonManager/LanguageManager.h | 1 + src/cpp/controller/EmailVerificationCode.cpp | 9 + src/cpp/controller/EmailVerificationCode.h | 2 + src/cpp/controller/User.cpp | 21 ++- src/cpp/controller/User.h | 5 + src/cpp/lib/MultithreadQueue.h | 1 + src/cpp/model/Email.cpp | 186 +++++++++++++++++++ src/cpp/model/Email.h | 56 ++++++ src/cpp/model/Session.cpp | 14 +- src/cpp/model/Session.h | 10 +- src/cpp/model/table/ElopageBuy.cpp | 2 +- src/cpp/model/table/ElopageBuy.h | 2 +- src/cpp/model/table/EmailOptIn.cpp | 2 +- src/cpp/model/table/EmailOptIn.h | 3 +- src/cpp/model/table/ModelBase.h | 42 ++++- src/cpp/model/table/User.cpp | 2 +- src/cpp/model/table/User.h | 2 +- 24 files changed, 462 insertions(+), 32 deletions(-) create mode 100644 src/cpp/SingletonManager/EmailManager.cpp create mode 100644 src/cpp/SingletonManager/EmailManager.h create mode 100644 src/cpp/model/Email.cpp create mode 100644 src/cpp/model/Email.h diff --git a/files_to_translate.txt b/files_to_translate.txt index 461042a11..ea55234ce 100644 --- a/files_to_translate.txt +++ b/files_to_translate.txt @@ -1,3 +1,4 @@ HTTPInterface/LoginPage.cpp HTTPInterface/CheckEmailPage.cpp model/Session.cpp +model/Email.cpp \ No newline at end of file diff --git a/src/cpp/Gradido_LoginServer.cpp b/src/cpp/Gradido_LoginServer.cpp index 73e404b41..5b689ab4f 100644 --- a/src/cpp/Gradido_LoginServer.cpp +++ b/src/cpp/Gradido_LoginServer.cpp @@ -7,7 +7,7 @@ #include "SingletonManager/ConnectionManager.h" #include "SingletonManager/SessionManager.h" - +#include "SingletonManager/EmailManager.h" #include "Poco/Util/HelpFormatter.h" #include "Poco/Net/ServerSocket.h" @@ -161,6 +161,7 @@ int Gradido_LoginServer::main(const std::vector& args) ServerConfig::g_ServerKeySeed->put(1, i1 | (i2 << 8)); ServerConfig::initEMailAccount(config()); + EmailManager::getInstance()->init(config()); // start cpu scheduler uint8_t worker_count = Poco::Environment::processorCount() * 2; diff --git a/src/cpp/HTTPInterface/ElopageWebhook.cpp b/src/cpp/HTTPInterface/ElopageWebhook.cpp index 85c1638b7..8584bc4d5 100644 --- a/src/cpp/HTTPInterface/ElopageWebhook.cpp +++ b/src/cpp/HTTPInterface/ElopageWebhook.cpp @@ -16,7 +16,7 @@ using namespace Poco::Data::Keywords; #include "../tasks/PrepareEmailTask.h" #include "../tasks/SendEmailTask.h" -#include "../model/EmailVerificationCode.h" +#include "../controller/EmailVerificationCode.h" #include "../model/table/ElopageBuy.h" @@ -301,7 +301,7 @@ int HandleElopageRequestTask::run() } // email verification code - auto emailVerification = model::EmailVerificationCode::create(user_id); + auto emailVerification = controller::EmailVerificationCode::create(user_id); //Poco::AutoPtr emailVerification(new model::table::EmailOptIn(user_id)); // create email verification code diff --git a/src/cpp/ServerConfig.cpp b/src/cpp/ServerConfig.cpp index 11e12f714..772da0503 100644 --- a/src/cpp/ServerConfig.cpp +++ b/src/cpp/ServerConfig.cpp @@ -114,7 +114,7 @@ namespace ServerConfig { g_EmailAccount.url = cfg.getString("email.smtp.url"); g_EmailAccount.port = cfg.getInt("email.smtp.port"); DISASM_FALSERET; - g_ServerKeySeed->put(3, DRRandom::r64()); + //g_ServerKeySeed->put(3, DRRandom::r64()); return true; } diff --git a/src/cpp/ServerConfig.h b/src/cpp/ServerConfig.h index 487344a2a..6f12b28c9 100644 --- a/src/cpp/ServerConfig.h +++ b/src/cpp/ServerConfig.h @@ -11,6 +11,7 @@ #include "SingletonManager/LanguageManager.h" + #define DISABLE_EMAIL namespace ServerConfig { @@ -20,9 +21,10 @@ namespace ServerConfig { MNEMONIC_BIP0039_SORTED_ORDER, MNEMONIC_MAX }; - + // depracted, moved to email manager struct EmailAccount { std::string sender; + std::string admin_receiver; std::string username; std::string password; std::string url; diff --git a/src/cpp/SingletonManager/EmailManager.cpp b/src/cpp/SingletonManager/EmailManager.cpp new file mode 100644 index 000000000..723aed337 --- /dev/null +++ b/src/cpp/SingletonManager/EmailManager.cpp @@ -0,0 +1,61 @@ +#include "EmailManager.h" +#include "../ServerConfig.h" + +#include "../Crypto/Obfus_array.h" +#include "../Crypto/DRRandom.h" + +EmailManager::EmailManager() + : mInitalized(false), mDisableEmail(false) +{ + + +} + +EmailManager::~EmailManager() +{ + exit(); + +} + +EmailManager* EmailManager::getInstance() +{ + static EmailManager theOne; + return &theOne; +} + +bool EmailManager::init(const Poco::Util::LayeredConfiguration& cfg) +{ + try { + mDisableEmail = cfg.getBool("email.disable", false); + mEmailAccount.sender = cfg.getString("email.sender"); + mEmailAccount.admin_receiver = cfg.getString("email.admin_receiver"); + mEmailAccount.username = cfg.getString("email.username"); + mEmailAccount.password = cfg.getString("email.password"); + mEmailAccount.url = cfg.getString("email.smtp.url"); + mEmailAccount.port = cfg.getInt("email.smtp.port"); + } + catch (Poco::Exception& ex) { + printf("email account not set in config: %s\n", ex.displayText().data()); + return false; + } + mInitalized = true; + + DISASM_FALSERET; + ServerConfig::g_ServerKeySeed->put(3, DRRandom::r64()); + + return true; +} + +void EmailManager::exit() +{ + model::Email* email = nullptr; + while (mPendingEmails.pop(email)) { + delete email; + } + mInitalized = false; +} + +int EmailManager::ThreadFunction() +{ + return 0; +} \ No newline at end of file diff --git a/src/cpp/SingletonManager/EmailManager.h b/src/cpp/SingletonManager/EmailManager.h new file mode 100644 index 000000000..568fa4427 --- /dev/null +++ b/src/cpp/SingletonManager/EmailManager.h @@ -0,0 +1,59 @@ +/*! +* +* \author: einhornimmond +* +* \date: 02.01.19 +* +* \brief: manage emails, send all emails with only one connection to mail server, on after on +*/ + +#ifndef GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_EMAIL_MANAGER_H +#define GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_EMAIL_MANAGER_H + +#include "Poco/AutoPtr.h" +#include "Poco/Util/LayeredConfiguration.h" + +#include "../lib/MultithreadQueue.h" +#include "../tasks/Thread.h" +#include "../model/Email.h" + +class EmailManager : public UniLib::lib::Thread +{ + +public: + ~EmailManager(); + + static EmailManager* getInstance(); + + bool init(const Poco::Util::LayeredConfiguration& cfg); + + inline const std::string& getAdminReceiver() { return mEmailAccount.admin_receiver; } + + inline void addEmail(model::Email* email) { mPendingEmails.push(email); } + +protected: + EmailManager(); + void exit(); + + int ThreadFunction(); + + struct EmailAccount { + std::string sender; + std::string admin_receiver; + std::string username; + std::string password; + std::string url; + int port; + }; + EmailAccount mEmailAccount; + + bool mInitalized; + bool mDisableEmail; + + UniLib::lib::MultithreadQueue mPendingEmails; + +}; + + + +#endif //GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_EMAIL_MANAGER_H \ No newline at end of file diff --git a/src/cpp/SingletonManager/LanguageManager.h b/src/cpp/SingletonManager/LanguageManager.h index 483fa3fc1..4e77c7f16 100644 --- a/src/cpp/SingletonManager/LanguageManager.h +++ b/src/cpp/SingletonManager/LanguageManager.h @@ -64,6 +64,7 @@ protected: Languages mThisLanguage; }; +// TODO: max cached catalog count class LanguageManager : protected UniLib::lib::MultithreadContainer { diff --git a/src/cpp/controller/EmailVerificationCode.cpp b/src/cpp/controller/EmailVerificationCode.cpp index a5d159fa1..6b98418f6 100644 --- a/src/cpp/controller/EmailVerificationCode.cpp +++ b/src/cpp/controller/EmailVerificationCode.cpp @@ -1,4 +1,5 @@ #include "EmailVerificationCode.h" +#include "../ServerConfig.h" #include "sodium.h" @@ -43,4 +44,12 @@ namespace controller { } return resultCode; } + + std::string EmailVerificationCode::getLink() + { + std::string link = ServerConfig::g_serverPath; + link += "/checkEmail/"; + link += std::to_string(getModel()->getCode()); + return link; + } } \ No newline at end of file diff --git a/src/cpp/controller/EmailVerificationCode.h b/src/cpp/controller/EmailVerificationCode.h index cf2308ab2..caca9186c 100644 --- a/src/cpp/controller/EmailVerificationCode.h +++ b/src/cpp/controller/EmailVerificationCode.h @@ -15,6 +15,8 @@ namespace controller { static Poco::AutoPtr create(int user_id); inline Poco::AutoPtr getModel() { return _getModel(); } + std::string getLink(); + protected: EmailVerificationCode(model::table::EmailOptIn* dbModel); static Poco::UInt64 createEmailVerificationCode(); diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 1b3da1ce9..941ef15ab 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -14,11 +14,22 @@ namespace controller { Poco::AutoPtr User::create() { - /*auto code = createEmailVerificationCode(); - auto db = new model::table::EmailOptIn(code, user_id); - auto result = new EmailVerificationCode(db); - return Poco::AutoPtr(result); - */ + auto db = new model::table::User(); + auto user = new User(db); + return Poco::AutoPtr(user); + } + Poco::AutoPtr User::create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/) + { + auto db = new model::table::User(email, first_name, last_name, passwordHashed, languageKey); + auto user = new User(db); + return Poco::AutoPtr(user); + } + + + int User::load(const unsigned char* pubkey_array) + { + Poco::Data::BLOB pubkey(pubkey_array, 32); + return getModel()->loadFromDB("pubkey", pubkey); } } \ No newline at end of file diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index ed45827ae..7bfd3bf0e 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -13,6 +13,11 @@ namespace controller { ~User(); static Poco::AutoPtr create(); + static Poco::AutoPtr create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de"); + + inline int load(const std::string& email) { return getModel()->loadFromDB("email", email); } + inline int load(int user_id) { return getModel()->loadFromDB("id", user_id); } + int load(const unsigned char* pubkey_array); inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/lib/MultithreadQueue.h b/src/cpp/lib/MultithreadQueue.h index 73c3e7d43..25b5af489 100644 --- a/src/cpp/lib/MultithreadQueue.h +++ b/src/cpp/lib/MultithreadQueue.h @@ -33,6 +33,7 @@ #define _DR_UNIVERSUM_LIB_LIB_MULTITHREAD_QUEUE_H__ #include "MultithreadContainer.h" +#include namespace UniLib { namespace lib { diff --git a/src/cpp/model/Email.cpp b/src/cpp/model/Email.cpp new file mode 100644 index 000000000..e99d5b82b --- /dev/null +++ b/src/cpp/model/Email.cpp @@ -0,0 +1,186 @@ +#include "Email.h" +#include "../SingletonManager/EmailManager.h" + +namespace model { + +const static char EmailText_emailVerification[] = {u8"\ +Hallo [first_name] [last_name],\n\ +\n\ +Du oder jemand anderes hat sich soeben mit dieser E-Mail Adresse bei Gradido registriert.\n\ +Wenn du es warst, klicke bitte auf den Link: [link]\n\ +oder kopiere den obigen Link in Dein Browserfenster.\n\ +\n\ +Mit freundlichen Grüßen\n\ +Dario, Gradido Server Admin\n\ +"}; + +const static char EmailText_emailResetPassword[] = { u8"\ +Hallo [first_name] [last_name],\n\ +\n\ +Du oder jemand anderes hat für dieses Konto ein Passwort Reset angefordert.\n\ +Wenn du es warst, klicke bitte auf den Link: [link]\n\ +oder kopiere den obigen Link in Dein Browserfenster.\n\ +\n\ +Mit freundlichen Grüßen\n\ +Dario, Gradido Server Admin\n\ +" }; + +const static char EmailText_adminEmailResetPassword[] = { u8"\ +Der Benutzer mit der Email-Adresse: [email] hat sein Passwort vergessen.\n\ +Außerdem hat er auch seine Passphrase vergessen. \n\ +Bitte logge dich im Admin-Bereich um das Problem zu lösen.\n\ +\n\ +LG \n\ +Gradido Login Server\ +" }; + + Email::Email(AutoPtr emailVerification, AutoPtr user, EmailType type) + : mEmailVerificationCode(emailVerification), mUser(user), mType(type) + { + + } + + + Email::Email(const std::string& errorHtml, EmailType type) + : mErrorHtml(errorHtml), mType(type) + { + } + + + bool Email::draft(Net::MailMessage* mailMessage, LanguageCatalog* langCatalog) + { + auto em = EmailManager::getInstance(); + auto adminRecipient = Net::MailRecipient(Net::MailRecipient::PRIMARY_RECIPIENT, em->getAdminReceiver()); + Poco::AutoPtr userTableModel; + if (!mUser.isNull()) { + userTableModel = mUser->getModel(); + } + static const char* functionName = "Email::draft"; + std::string content; + + switch (mType) { + case EMAIL_DEFAULT: + mailMessage->addRecipient(adminRecipient); + mailMessage->setSubject(langCatalog->gettext_str("Default Email Subject")); + mailMessage->addContent(new Poco::Net::StringPartSource(langCatalog->gettext_str("Empty Email Content"))); + return true; + + case EMAIL_ERROR: + mailMessage->addRecipient(adminRecipient); + mailMessage->setSubject(langCatalog->gettext_str("Error from Gradido Login Server")); + mailMessage->addContent(new Poco::Net::StringPartSource(mErrorHtml)); + return true; + + case EMAIL_USER_VERIFICATION_CODE: + if (userTableModel.isNull() || mUser->getModel()->getEmail() == "") { + addError(new Error(functionName, "no receiver email set for user email verification email")); + return false; + } + if (mEmailVerificationCode.isNull()) { + addError(new Error(functionName, "no email verification code set for user email verification email")); + return false; + } + mailMessage->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, mUser->getModel()->getEmail())); + mailMessage->setSubject(langCatalog->gettext_str("Gradido: E-Mail Verification")); + + mailMessage->addContent( + new Poco::Net::StringPartSource(replaceUserNamesAndLink( + langCatalog->gettext(EmailText_emailVerification), + userTableModel->getFirstName(), + userTableModel->getLastName(), + mEmailVerificationCode->getLink() + )) + ); + return true; + case EMAIL_USER_RESET_PASSWORD: + if (userTableModel.isNull() || mUser->getModel()->getEmail() == "") { + addError(new Error(functionName, "no receiver email set for user reset password email")); + return false; + } + if (mEmailVerificationCode.isNull()) { + addError(new Error(functionName, "no email verification code set for user reset password email")); + return false; + } + mailMessage->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, mUser->getModel()->getEmail())); + mailMessage->setSubject(langCatalog->gettext_str(u8"Gradido: Passwort zurücksetzen")); + + mailMessage->addContent( + new Poco::Net::StringPartSource(replaceUserNamesAndLink( + langCatalog->gettext(EmailText_emailResetPassword), + userTableModel->getFirstName(), + userTableModel->getLastName(), + mEmailVerificationCode->getLink() + )) + ); + return true; + case EMAIL_ADMIN_RESET_PASSWORD_REQUEST_WITHOUT_MEMORIZED_PASSPHRASE: + if (userTableModel.isNull() || mUser->getModel()->getEmail() == "") { + addError(new Error(functionName, "no user email set for admin reset password email")); + return false; + } + + mailMessage->addRecipient(adminRecipient); + mailMessage->setSubject(langCatalog->gettext_str("Reset Password Request without memorized passphrase")); + mailMessage->addContent( + new Poco::Net::StringPartSource(replaceEmail( + EmailText_adminEmailResetPassword, + userTableModel->getEmail() + )) + ); + return true; + default: return false; + } + + return false; + } + + std::string Email::replaceUserNamesAndLink(const char* src, const std::string& first_name, const std::string& last_name, const std::string& link) + { + std::string result = src; + int findCursor = 0; + static const char* functionName = "Email::replaceUserNamesAndLink"; + + int findPos = result.find("[first_name]", findCursor); + if (findPos != result.npos) { + findCursor = findPos + 13; + result.replace(findPos, 12, first_name); + } + else { + addError(new Error(functionName, "no first_name placeholder found")); + } + + findPos = result.find("[last_name]", findCursor); + if (findPos != result.npos) { + findCursor = findPos + 12; + result.replace(findPos, 11, last_name); + } + else { + addError(new Error(functionName, "no last_name placeholder found")); + } + + findPos = result.find("[link]", findCursor); + if (findPos != result.npos) { + findCursor = findPos + 7; + result.replace(findPos, 6, link); + } + else { + addError(new Error(functionName, "no email placeholder found")); + } + return result; + } + + std::string Email::replaceEmail(const char* src, const std::string& email) + { + std::string result = src; + static const char* functionName = "Email::replaceEmail"; + + int findPos = result.find("[email]"); + if (findPos != result.npos) { + result.replace(findPos, 7, email); + } + else { + addError(new Error(functionName, "no email placeholder found")); + } + return result; + } +} \ No newline at end of file diff --git a/src/cpp/model/Email.h b/src/cpp/model/Email.h new file mode 100644 index 000000000..0c03bc513 --- /dev/null +++ b/src/cpp/model/Email.h @@ -0,0 +1,56 @@ +/*! +* +* \author: einhornimmond +* +* \date: 02.01.20 +* +* \brief: store email for +*/ + +#ifndef GRADIDO_LOGIN_SERVER_MODEL_EMAIL_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_EMAIL_INCLUDE + +#include "Poco/Net/MailMessage.h" + +#include "../controller/EmailVerificationCode.h" +#include "../controller/User.h" + +#include "../SingletonManager/LanguageManager.h" + +#include "../lib/ErrorList.h" + +namespace model { + using namespace Poco; + + enum EmailType + { + EMAIL_DEFAULT, + EMAIL_ERROR, + EMAIL_USER_VERIFICATION_CODE, + EMAIL_USER_RESET_PASSWORD, + EMAIL_ADMIN_RESET_PASSWORD_REQUEST_WITHOUT_MEMORIZED_PASSPHRASE + }; + + class Email: public ErrorList + { + public: + Email(AutoPtr emailVerification, AutoPtr user, EmailType type); + //! \param errors copy errors into own memory + Email(const std::string& errorHtml, EmailType type); + + inline EmailType getType() { return mType; } + + bool draft(Net::MailMessage* mailMessage, LanguageCatalog* langCatalog); + + protected: + std::string replaceUserNamesAndLink(const char* src, const std::string& first_name, const std::string& last_name, const std::string& link); + std::string replaceEmail(const char* src, const std::string& email); + + AutoPtr mEmailVerificationCode; + AutoPtr mUser; + std::string mErrorHtml; + EmailType mType; + }; +} + +#endif //GRADIDO_LOGIN_SERVER_MODEL_EMAIL_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index ce953b652..2073a3119 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -84,7 +84,7 @@ int WritePassphraseIntoDB::run() // -------------------------------------------------------------------------------------------------------------- Session::Session(int handle) - : mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mEmailVerificationCodeObject(nullptr), mState(SESSION_STATE_EMPTY), mActive(false) + : mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mState(SESSION_STATE_EMPTY), mActive(false) { } @@ -106,10 +106,8 @@ void Session::reset() lock("Session::reset"); mSessionUser = nullptr; - if (mEmailVerificationCodeObject) { - delete mEmailVerificationCodeObject; - mEmailVerificationCodeObject = nullptr; - } + mNewUser = nullptr; + mEmailVerificationCodeObject = nullptr; // watch out //updateTimeout(); @@ -131,7 +129,7 @@ void Session::updateTimeout() unlock(); } -controller::EmailVerificationCode* Session::getEmailVerificationCodeObject() +Poco::AutoPtr Session::getEmailVerificationCodeObject() { lock("Session::getEmailVerificationCodeObject"); auto ret = mEmailVerificationCodeObject; @@ -376,7 +374,9 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode) bool Session::createNewEmailVerificationCode() { - return false; + mEmailVerificationCodeObject = controller::EmailVerificationCode::create(mNewUser->getModel()->getID()); + + return true; } bool Session::startProcessingTransaction(const std::string& proto_message_base64) diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index 73a904cfc..fc576c25e 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -12,6 +12,7 @@ #include "../lib/ErrorList.h" #include "User.h" +#include "../controller/User.h" #include "../lib/MultithreadContainer.h" #include "../tasks/ProcessingTransaction.h" @@ -57,7 +58,10 @@ public: ~Session(); // get new model objects - controller::EmailVerificationCode* getEmailVerificationCodeObject(); + Poco::AutoPtr getEmailVerificationCodeObject(); + + // set new model objects + inline void setUser(Poco::AutoPtr user) { mNewUser = user; } // ---------------- User functions ---------------------------- // TODO: automatic redirect after some time, median profiled time for register @@ -69,6 +73,7 @@ public: inline void setUser(Poco::AutoPtr user) { mSessionUser = user; } + bool deleteUser(); Poco::AutoPtr getUser() { @@ -144,11 +149,12 @@ protected: private: int mHandleId; Poco::AutoPtr mSessionUser; + Poco::AutoPtr mNewUser; std::string mPassphrase; Poco::DateTime mLastActivity; Poco::Net::IPAddress mClientLoginIP; Poco::UInt64 mEmailVerificationCode; - controller::EmailVerificationCode* mEmailVerificationCodeObject; + Poco::AutoPtr mEmailVerificationCodeObject; SessionStates mState; diff --git a/src/cpp/model/table/ElopageBuy.cpp b/src/cpp/model/table/ElopageBuy.cpp index 2db6e9574..c6005a1be 100644 --- a/src/cpp/model/table/ElopageBuy.cpp +++ b/src/cpp/model/table/ElopageBuy.cpp @@ -67,7 +67,7 @@ namespace model { } - Poco::Data::Statement ElopageBuy::_loadFromDB(Poco::Data::Session session, std::string& fieldName) + Poco::Data::Statement ElopageBuy::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { // Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/ElopageBuy.h b/src/cpp/model/table/ElopageBuy.h index b9c58baf6..cde99c9ca 100644 --- a/src/cpp/model/table/ElopageBuy.h +++ b/src/cpp/model/table/ElopageBuy.h @@ -38,7 +38,7 @@ namespace model { protected: - Poco::Data::Statement _loadFromDB(Poco::Data::Session session, std::string& fieldName); + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); Poco::Int32 mIDs[ELOPAGE_BUY_MAX]; diff --git a/src/cpp/model/table/EmailOptIn.cpp b/src/cpp/model/table/EmailOptIn.cpp index c8a35af59..359515ca4 100644 --- a/src/cpp/model/table/EmailOptIn.cpp +++ b/src/cpp/model/table/EmailOptIn.cpp @@ -37,7 +37,7 @@ namespace model { } - Poco::Data::Statement EmailOptIn::_loadFromDB(Poco::Data::Session session, std::string& fieldName) + Poco::Data::Statement EmailOptIn::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/EmailOptIn.h b/src/cpp/model/table/EmailOptIn.h index 45ed21ead..ba2a6bcd1 100644 --- a/src/cpp/model/table/EmailOptIn.h +++ b/src/cpp/model/table/EmailOptIn.h @@ -19,8 +19,9 @@ namespace model { const char* getTableName() { return "email_opt_in"; } inline Poco::UInt64 getCode() const { return mEmailVerificationCode; } + inline void setCode(Poco::UInt64 code) { mEmailVerificationCode = code; } protected: - Poco::Data::Statement _loadFromDB(Poco::Data::Session session, std::string& fieldName); + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); // data type must be a multiple of 4 diff --git a/src/cpp/model/table/ModelBase.h b/src/cpp/model/table/ModelBase.h index 202fb7b0c..6794c2fe2 100644 --- a/src/cpp/model/table/ModelBase.h +++ b/src/cpp/model/table/ModelBase.h @@ -9,6 +9,8 @@ #include "../../MySQL/MysqlTable.h" +//using namespace Poco::Data::Keywords; + namespace model { namespace table { @@ -21,8 +23,8 @@ namespace model { virtual const char* getTableName() = 0; - template size_t updateIntoDB(const std::string& fieldName, T fieldValue ); - template size_t loadFromDB(const std::string& fieldName, T fieldValue); + template size_t updateIntoDB(const std::string& fieldName, const T& fieldValue ); + template size_t loadFromDB(const std::string& fieldName, const T& fieldValue); bool insertIntoDB(); inline void setID(int id) { lock(); mID = id; unlock(); } @@ -35,7 +37,7 @@ namespace model { void release(); protected: - virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, std::string& fieldName) = 0; + virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName) = 0; virtual Poco::Data::Statement _insertIntoDB(Poco::Data::Session session) = 0; int mID; @@ -46,11 +48,11 @@ namespace model { }; template - size_t ModelBase::loadFromDB(const std::string& fieldName, T fieldValue) + size_t ModelBase::loadFromDB(const std::string& fieldName, const T& fieldValue) { auto cm = ConnectionManager::getInstance(); Poco::Data::Statement select = _loadFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER), fieldName); - select, use(fieldValue); + select, Poco::Data::Keywords::useRef(fieldValue); size_t resultCount = 0; try { @@ -66,7 +68,7 @@ namespace model { } template - size_t ModelBase::updateIntoDB(const std::string& fieldName, T fieldValue) + size_t ModelBase::updateIntoDB(const std::string& fieldName, const T& fieldValue) { auto cm = ConnectionManager::getInstance(); Poco::Data::Statement update(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); @@ -77,7 +79,7 @@ namespace model { } update << "UPDATE " << getTableName() << " SET " << fieldName << " = ? where id = ?", - use(fieldValue), use(mID); + Poco::Data::Keywords::useRef(fieldValue), Poco::Data::Keywords::use(mID); size_t resultCount = 0; try { @@ -107,6 +109,32 @@ namespace model { Poco::AutoPtr mModel; }; + + + template + class ModelUpdateTask : public UniLib::controller::CPUTask + { + public: + ModelUpdateTask(Poco::AutoPtr model, const std::string& fieldName, const T& fieldValue) + : UniLib::controller::CPUTask(ServerConfig::g_CPUScheduler), mModel(model), mFieldName(fieldName), mFieldValue(fieldValue) + { +#ifdef _UNI_LIB_DEBUG + setName(model->getTableName()); +#endif + } + + int run() { + mModel->updateIntoDB(mFieldName, mFieldValue); + } + const char* getResourceType() const { return "ModelUpdateTask"; }; + + protected: + Poco::AutoPtr mModel; + std::string mFieldName; + T mFieldValue; + }; + + } } diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index eb101f0f9..5fa9bb954 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -61,7 +61,7 @@ namespace model { return insert; } - Poco::Data::Statement User::_loadFromDB(Poco::Data::Session session, std::string& fieldName) + Poco::Data::Statement User::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) { Poco::Data::Statement select(session); diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index a85524987..9073d6ffb 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -60,7 +60,7 @@ namespace model { protected: - Poco::Data::Statement _loadFromDB(Poco::Data::Session session, std::string& fieldName); + Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName); // insert only with email, first_name, last_name, password if exist and language Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);