mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
filter elopage products, save elopage buys
This commit is contained in:
parent
0181d8fef6
commit
0c00a3e809
@ -16,6 +16,7 @@ using namespace Poco::Data::Keywords;
|
||||
#include "../tasks/SendEmailTask.h"
|
||||
|
||||
#include "../model/EmailVerificationCode.h"
|
||||
#include "../model/ElopageBuy.h"
|
||||
|
||||
|
||||
|
||||
@ -100,6 +101,8 @@ void ElopageWebhook::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
|
||||
if (event == "lesson.viewed") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// write stream result also to file
|
||||
static Poco::Mutex mutex;
|
||||
@ -175,6 +178,7 @@ void HandleElopageRequestTask::writeUserIntoDB()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HandleElopageRequestTask::getUserIdFromDB()
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
@ -203,87 +207,118 @@ int HandleElopageRequestTask::run()
|
||||
return 0;
|
||||
}
|
||||
|
||||
mEmail = mRequestData.get("payer[email]", "");
|
||||
mFirstName = mRequestData.get("payer[first_name]", "");
|
||||
mLastName = mRequestData.get("payer[last_name]", "");
|
||||
std::string order_id = mRequestData.get("order_id", "");
|
||||
// elopage buy
|
||||
Poco::AutoPtr<ElopageBuy> elopageBuy(new ElopageBuy(mRequestData));
|
||||
if (elopageBuy->errorCount() > 0) {
|
||||
getErrors(elopageBuy);
|
||||
}
|
||||
UniLib::controller::TaskPtr saveElopageBuy(new ModelInsertTask(elopageBuy));
|
||||
saveElopageBuy->scheduleTask(saveElopageBuy);
|
||||
|
||||
// check product id
|
||||
Poco::UInt64 product_id = 0;
|
||||
try {
|
||||
product_id = stoull(mRequestData.get("product[id]", "0"));
|
||||
}
|
||||
catch (const std::invalid_argument& ia) {
|
||||
std::cerr << __FUNCTION__ << "Invalid argument: " << ia.what() << '\n';
|
||||
}
|
||||
catch (const std::out_of_range& oor) {
|
||||
std::cerr << __FUNCTION__ << "Out of Range error: " << oor.what() << '\n';
|
||||
}
|
||||
catch (const std::logic_error & ler) {
|
||||
std::cerr << __FUNCTION__ << "Logical error: " << ler.what() << '\n';
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << __FUNCTION__ << "Unknown error" << '\n';
|
||||
}
|
||||
std::string order_id = mRequestData.get("order_id", "");
|
||||
addError(new ParamError("HandleElopageRequestTask", "order_id", order_id.data()));
|
||||
|
||||
// validate input
|
||||
if (!validateInput()) {
|
||||
// if input is invalid we can stop now
|
||||
sendErrorsAsEmail();
|
||||
return -1;
|
||||
// only for product 36001 and 43741 create user accounts and send emails
|
||||
if (product_id == 36001 || product_id == 43741) {
|
||||
mEmail = mRequestData.get("payer[email]", "");
|
||||
mFirstName = mRequestData.get("payer[first_name]", "");
|
||||
mLastName = mRequestData.get("payer[last_name]", "");
|
||||
|
||||
// validate input
|
||||
if (!validateInput()) {
|
||||
// if input is invalid we can stop now
|
||||
sendErrorsAsEmail();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if user exist we can stop now
|
||||
if (getUserIdFromDB()) {
|
||||
sendErrorsAsEmail();
|
||||
return -2;
|
||||
}
|
||||
|
||||
// if user with this email didn't exist
|
||||
// we can create a new user and send a email to him
|
||||
|
||||
// prepare email in advance
|
||||
// create connection to email server
|
||||
UniLib::controller::TaskPtr prepareEmail(new PrepareEmailTask(ServerConfig::g_CPUScheduler));
|
||||
prepareEmail->scheduleTask(prepareEmail);
|
||||
|
||||
// write user entry into db
|
||||
writeUserIntoDB();
|
||||
|
||||
// get user id from db
|
||||
int user_id = getUserIdFromDB();
|
||||
// we didn't get a user_id, something went wrong
|
||||
if (!user_id) {
|
||||
addError(new Error("User loadEntryDBId", "user_id is zero"));
|
||||
sendErrorsAsEmail();
|
||||
return -3;
|
||||
}
|
||||
|
||||
// email verification code
|
||||
Poco::AutoPtr<EmailVerificationCode> emailVerification(new EmailVerificationCode(user_id));
|
||||
|
||||
// create email verification code
|
||||
if (!emailVerification->getCode()) {
|
||||
// exit if email verification code is empty
|
||||
addError(new Error("Email verification", "code is empty, error in random?"));
|
||||
sendErrorsAsEmail();
|
||||
return -4;
|
||||
}
|
||||
|
||||
// write email verification code into db
|
||||
UniLib::controller::TaskPtr saveEmailVerificationCode(new ModelInsertTask(emailVerification));
|
||||
saveEmailVerificationCode->scheduleTask(saveEmailVerificationCode);
|
||||
|
||||
// send email to user
|
||||
auto message = new Poco::Net::MailMessage;
|
||||
|
||||
message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, mEmail));
|
||||
message->setSubject("Gradido: E-Mail Verification");
|
||||
std::stringstream ss;
|
||||
ss << "Hallo " << mFirstName << " " << mLastName << "," << std::endl << std::endl;
|
||||
ss << "Du oder jemand anderes hat sich soeben mit dieser E-Mail Adresse bei Gradido registriert. " << std::endl;
|
||||
ss << "Wenn du es warst, klicke bitte auf den Link: " << ServerConfig::g_serverPath << "/checkEmail/" << emailVerification->getCode() << std::endl;
|
||||
//ss << "oder kopiere den Code: " << mEmailVerificationCode << " selbst dort hinein." << std::endl;
|
||||
ss << "oder kopiere den obigen Link in Dein Browserfenster." << std::endl;
|
||||
ss << std::endl;
|
||||
ss << "Mit freundlichen Grüße" << std::endl;
|
||||
ss << "Dario, Gradido Server Admin" << std::endl;
|
||||
|
||||
message->addContent(new Poco::Net::StringPartSource(ss.str()));
|
||||
|
||||
UniLib::controller::TaskPtr sendEmail(new SendEmailTask(message, ServerConfig::g_CPUScheduler, 1));
|
||||
sendEmail->setParentTaskPtrInArray(prepareEmail, 0);
|
||||
sendEmail->setParentTaskPtrInArray(saveEmailVerificationCode, 1);
|
||||
sendEmail->scheduleTask(sendEmail);
|
||||
}
|
||||
|
||||
// if user exist we can stop now
|
||||
if (getUserIdFromDB()) {
|
||||
sendErrorsAsEmail();
|
||||
return -2;
|
||||
}
|
||||
|
||||
// if user with this email didn't exist
|
||||
// we can create a new user and send a email to him
|
||||
|
||||
// prepare email in advance
|
||||
// create connection to email server
|
||||
UniLib::controller::TaskPtr prepareEmail(new PrepareEmailTask(ServerConfig::g_CPUScheduler));
|
||||
prepareEmail->scheduleTask(prepareEmail);
|
||||
|
||||
// write user entry into db
|
||||
writeUserIntoDB();
|
||||
|
||||
// get user id from db
|
||||
int user_id = getUserIdFromDB();
|
||||
// we didn't get a user_id, something went wrong
|
||||
if (!user_id) {
|
||||
addError(new Error("User loadEntryDBId", "user_id is zero"));
|
||||
sendErrorsAsEmail();
|
||||
return -3;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<EmailVerificationCode> emailVerification(new EmailVerificationCode(user_id));
|
||||
|
||||
// create email verification code
|
||||
if (!emailVerification->getCode()) {
|
||||
// exit if email verification code is empty
|
||||
addError(new Error("Email verification", "code is empty, error in random?"));
|
||||
sendErrorsAsEmail();
|
||||
return -4;
|
||||
}
|
||||
|
||||
// write email verification code into db
|
||||
UniLib::controller::TaskPtr saveEmailVerificationCode(new ModelInsertTask(emailVerification));
|
||||
saveEmailVerificationCode->scheduleTask(saveEmailVerificationCode);
|
||||
|
||||
// send email to user
|
||||
auto message = new Poco::Net::MailMessage;
|
||||
|
||||
message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, mEmail));
|
||||
message->setSubject("Gradido: E-Mail Verification");
|
||||
std::stringstream ss;
|
||||
ss << "Hallo " << mFirstName << " " << mLastName << "," << std::endl << std::endl;
|
||||
ss << "Du oder jemand anderes hat sich soeben mit dieser E-Mail Adresse bei Elopage für Gradido angemeldet. " << std::endl;
|
||||
ss << "Um dein Gradido Konto anzulegen und deine E-Mail zu bestätigen," << std::endl;
|
||||
ss << "klicke bitte auf den Link: https://gradido2.dario-rekowski.de/account/checkEmail/" << emailVerification->getCode() << std::endl;
|
||||
ss << "oder kopiere den Code: " << emailVerification->getCode() << " selbst dort hinein." << std::endl << std::endl;
|
||||
ss << "Mit freundlichen Grüße" << std::endl;
|
||||
ss << "Dario, Gradido Server Admin" << std::endl;
|
||||
|
||||
|
||||
message->addContent(new Poco::Net::StringPartSource(ss.str()));
|
||||
|
||||
UniLib::controller::TaskPtr sendEmail(new SendEmailTask(message, ServerConfig::g_CPUScheduler, 1));
|
||||
sendEmail->setParentTaskPtrInArray(prepareEmail, 0);
|
||||
sendEmail->setParentTaskPtrInArray(saveEmailVerificationCode, 1);
|
||||
sendEmail->scheduleTask(sendEmail);
|
||||
|
||||
// if errors occured, send via email
|
||||
//if (errorCount() > 1) {
|
||||
if (errorCount() > 1) {
|
||||
sendErrorsAsEmail();
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -179,15 +179,15 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
auto str = uri.substr(pos + 1);
|
||||
verificationCode = stoull(uri.substr(pos + 1));
|
||||
} catch (const std::invalid_argument& ia) {
|
||||
std::cerr << "Invalid argument: " << ia.what() << '\n';
|
||||
std::cerr << __FUNCTION__ << "Invalid argument: " << ia.what() << '\n';
|
||||
} catch (const std::out_of_range& oor) {
|
||||
std::cerr << "Out of Range error: " << oor.what() << '\n';
|
||||
std::cerr << __FUNCTION__ << "Out of Range error: " << oor.what() << '\n';
|
||||
}
|
||||
catch (const std::logic_error & ler) {
|
||||
std::cerr << "Logical error: " << ler.what() << '\n';
|
||||
std::cerr << __FUNCTION__ << "Logical error: " << ler.what() << '\n';
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << "Unknown error" << '\n';
|
||||
std::cerr << __FUNCTION__ << "Unknown error" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include "Poco/Mutex.h"
|
||||
#include <time.h>
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
MysqlTable::MysqlTable(size_t fieldCount)
|
||||
: mFieldCount(fieldCount), mHeader(nullptr)
|
||||
{
|
||||
@ -114,7 +116,7 @@ time_t MysqlTable::parseFromMysqlDateTime(const char* mysql_date_time)
|
||||
|
||||
struct tm * parsedTime;
|
||||
// used because localtime return an internal pointer, not thread safe
|
||||
static Poco::Mutex timeMutex;
|
||||
Poco::Mutex& timeMutex = ServerConfig::g_TimeMutex;
|
||||
|
||||
int year, month, day, hour, minute, second;
|
||||
// ex: 2009-10-29
|
||||
|
||||
@ -39,6 +39,7 @@ namespace ServerConfig {
|
||||
int g_SessionTimeout = SESSION_TIMEOUT_DEFAULT;
|
||||
std::string g_serverPath;
|
||||
std::string g_php_serverPath;
|
||||
Poco::Mutex g_TimeMutex;
|
||||
|
||||
bool loadMnemonicWordLists()
|
||||
{
|
||||
|
||||
@ -38,6 +38,7 @@ namespace ServerConfig {
|
||||
extern int g_SessionTimeout;
|
||||
extern std::string g_serverPath;
|
||||
extern std::string g_php_serverPath;
|
||||
extern Poco::Mutex g_TimeMutex;
|
||||
|
||||
|
||||
bool loadMnemonicWordLists();
|
||||
|
||||
76
src/cpp/model/ElopageBuy.cpp
Normal file
76
src/cpp/model/ElopageBuy.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "ElopageBuy.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
const static std::string g_requestFieldsNames[] = {
|
||||
"product[affiliate_program_id]", "publisher[id]", "order_id", "product_id",
|
||||
"product[price]", "payer[email]", "payment_state", "success_date", "event" };
|
||||
|
||||
ElopageBuy::ElopageBuy(const Poco::Net::NameValueCollection& elopage_webhook_requestData)
|
||||
: mPayed(false)
|
||||
{
|
||||
memset(mIDs, 0, ELOPAGE_BUY_MAX * sizeof(Poco::Int32));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
std::string temp = elopage_webhook_requestData.get(g_requestFieldsNames[i], "0");
|
||||
//printf("get: %s for field: %s (%d)\n", temp.data(), g_requestFieldsNames[i].data(), i);
|
||||
try {
|
||||
if (i == 4) {
|
||||
mIDs[i+1] = static_cast<Poco::Int32>(round(stof(temp) * 100.0f));
|
||||
}
|
||||
else {
|
||||
mIDs[i+1] = stoul(temp);
|
||||
}
|
||||
}
|
||||
catch (const std::invalid_argument& ia) {addError(new ParamError("ElopageBuy", "parse string to number, invalid argument", ia.what()));}
|
||||
catch (const std::out_of_range& oor) { addError(new ParamError("ElopageBuy", "parse string to number, Out of Range error", oor.what()));}
|
||||
catch (const std::logic_error & ler) { addError(new ParamError("ElopageBuy", "parse string to number, Logical error", ler.what()));}
|
||||
catch (...) {addError(new Error("ElopageBuy", "parse string to number, unknown error"));}
|
||||
}
|
||||
mPayerEmail = elopage_webhook_requestData.get(g_requestFieldsNames[5], "");
|
||||
std::string payed = elopage_webhook_requestData.get(g_requestFieldsNames[6], "");
|
||||
// payment_state = paid
|
||||
if (payed == "paid") mPayed = true;
|
||||
|
||||
mSuccessDate = parseElopageDate(elopage_webhook_requestData.get(g_requestFieldsNames[7], ""));
|
||||
mEvent = elopage_webhook_requestData.get(g_requestFieldsNames[8], "");
|
||||
}
|
||||
|
||||
ElopageBuy::~ElopageBuy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
ELOPAGE_BUY_AFFILIATE_PROGRAM_ID,
|
||||
ELOPAGE_BUY_PUBLISHER_ID,
|
||||
ELOPAGE_BUY_ORDER_ID,
|
||||
ELOPAGE_BUY_PRODUCT_ID,
|
||||
ELOPAGE_BUY_PRODUCT_PRICE
|
||||
*/
|
||||
|
||||
Poco::Data::Statement ElopageBuy::insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
|
||||
lock();
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (affiliate_program_id, publisher_id, order_id, product_id, product_price, payer_email, payed, success_date, event) "
|
||||
<< " VALUES(?,?,?,?,?,?,?,?,?)"
|
||||
, bind(mIDs[ELOPAGE_BUY_AFFILIATE_PROGRAM_ID]), bind(mIDs[ELOPAGE_BUY_PUBLISHER_ID])
|
||||
, bind(mIDs[ELOPAGE_BUY_ORDER_ID]), bind(mIDs[ELOPAGE_BUY_PRODUCT_ID]), bind(mIDs[ELOPAGE_BUY_PRODUCT_PRICE])
|
||||
, bind(mPayerEmail), bind(mPayed), bind(mSuccessDate), bind(mEvent);
|
||||
unlock();
|
||||
return insert;
|
||||
|
||||
}
|
||||
Poco::Data::Statement ElopageBuy::updateIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
throw Poco::Exception("ElopageBuy::updateIntoDB not implemented");
|
||||
}
|
||||
Poco::Data::Statement ElopageBuy::loadFromDB(Poco::Data::Session session, std::string& fieldName)
|
||||
{
|
||||
// Poco::Data::Statement select(session);
|
||||
|
||||
throw Poco::Exception("ElopageBuy::loadFromDB not implemented");
|
||||
|
||||
}
|
||||
51
src/cpp/model/ElopageBuy.h
Normal file
51
src/cpp/model/ElopageBuy.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_ELOPAGE_BUY_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_ELOPAGE_BUY_INCLUDE
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 31.10.2019
|
||||
*
|
||||
* @brief: Model for handling Elopage publisher
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ModelBase.h"
|
||||
#include "Poco/Types.h"
|
||||
#include "Poco/Net/NameValueCollection.h"
|
||||
|
||||
|
||||
enum ElopageBuyId {
|
||||
ELOPAGE_BUY_ID,
|
||||
ELOPAGE_BUY_AFFILIATE_PROGRAM_ID,
|
||||
ELOPAGE_BUY_PUBLISHER_ID,
|
||||
ELOPAGE_BUY_ORDER_ID,
|
||||
ELOPAGE_BUY_PRODUCT_ID,
|
||||
ELOPAGE_BUY_PRODUCT_PRICE,
|
||||
|
||||
ELOPAGE_BUY_MAX
|
||||
};
|
||||
|
||||
class ElopageBuy : public ModelBase
|
||||
{
|
||||
public:
|
||||
ElopageBuy(const Poco::Net::NameValueCollection& elopage_webhook_requestData);
|
||||
~ElopageBuy();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() { return "elopage_buys"; }
|
||||
Poco::Data::Statement insertIntoDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement updateIntoDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement loadFromDB(Poco::Data::Session session, std::string& fieldName);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
Poco::Int32 mIDs[ELOPAGE_BUY_MAX];
|
||||
std::string mPayerEmail;
|
||||
bool mPayed;
|
||||
Poco::DateTime mSuccessDate;
|
||||
std::string mEvent;
|
||||
};
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_ELOPAGE_BUY_INCLUDE
|
||||
@ -1,9 +1,12 @@
|
||||
#include "ModelBase.h"
|
||||
#include "sodium.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
#include "../SingletonManager/ConnectionManager.h"
|
||||
|
||||
#include "Poco/URI.h"
|
||||
|
||||
ModelInsertTask::ModelInsertTask(Poco::AutoPtr<ModelBase> model)
|
||||
: UniLib::controller::CPUTask(ServerConfig::g_CPUScheduler), mModel(model)
|
||||
{
|
||||
@ -50,4 +53,41 @@ void ModelBase::release()
|
||||
}
|
||||
unlock();
|
||||
|
||||
}
|
||||
|
||||
Poco::DateTime ModelBase::parseElopageDate(std::string dateString)
|
||||
{
|
||||
std::string decodedDateString = "";
|
||||
Poco::URI::decode(dateString, decodedDateString);
|
||||
|
||||
struct tm * parsedTime;
|
||||
// used because localtime return an internal pointer, not thread safe
|
||||
Poco::Mutex& timeMutex = ServerConfig::g_TimeMutex;
|
||||
|
||||
int year, month, day, hour, minute, second;
|
||||
// ex: 2009-10-29
|
||||
if (sscanf(decodedDateString.data(), "%d-%d-%dT%d:%dZ", &year, &month, &day, &hour, &minute) != EOF) {
|
||||
time_t rawTime;
|
||||
time(&rawTime);
|
||||
|
||||
// static, used for every thread
|
||||
timeMutex.lock();
|
||||
parsedTime = localtime(&rawTime);
|
||||
|
||||
// tm_year is years since 1900
|
||||
parsedTime->tm_year = year - 1900;
|
||||
// tm_months is months since january
|
||||
parsedTime->tm_mon = month - 1;
|
||||
parsedTime->tm_mday = day;
|
||||
parsedTime->tm_hour = hour;
|
||||
parsedTime->tm_min = minute;
|
||||
parsedTime->tm_sec = 0;
|
||||
|
||||
rawTime = mktime(parsedTime);
|
||||
timeMutex.unlock();
|
||||
// rawTime is in seconds, poco timestamp in microseconds
|
||||
return Poco::DateTime(Poco::Timestamp(rawTime* 1000000));
|
||||
}
|
||||
|
||||
return Poco::DateTime(Poco::Timestamp());
|
||||
}
|
||||
@ -25,6 +25,8 @@ public:
|
||||
inline void setID(int id) { lock(); mID = id; unlock(); }
|
||||
inline int getID() { lock(); int id = mID; unlock(); return id; }
|
||||
|
||||
static Poco::DateTime parseElopageDate(std::string dateString);
|
||||
|
||||
// for poco auto ptr
|
||||
void duplicate();
|
||||
void release();
|
||||
|
||||
@ -50,7 +50,7 @@ label:not(.grd_radio_label) {
|
||||
<body>
|
||||
<div class="versionstring dev-info">
|
||||
<p class="grd_small">Login Server in Entwicklung</p>
|
||||
<p class="grd_small">Alpha 0.4.3</p>
|
||||
<p class="grd_small">Alpha 0.4.4</p>
|
||||
</div>
|
||||
<!--<nav class="grd-left-bar expanded" data-topbar role="navigation">
|
||||
<div class="grd-left-bar-section">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user