add function to search for verification emails to resend at startup and by register direct

This commit is contained in:
Dario 2020-06-15 17:37:02 +02:00
parent 1573b1f70c
commit f414ca8ddb
6 changed files with 77 additions and 1 deletions

View File

@ -9,6 +9,8 @@
#include "SingletonManager/SessionManager.h"
#include "SingletonManager/EmailManager.h"
#include "controller/User.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/HTTPServer.h"
@ -192,7 +194,8 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
return Application::EXIT_CONFIG;
}
// schedule email verification resend
controller::User::checkIfVerificationEmailsShouldBeResend(ServerConfig::g_CronJobsTimer);
// HTTP Interface Server
// set-up a server socket

View File

@ -40,6 +40,7 @@ namespace ServerConfig {
UniLib::controller::CPUSheduler* g_CPUScheduler = nullptr;
UniLib::controller::CPUSheduler* g_CryptoCPUScheduler = nullptr;
Context::Ptr g_SSL_CLient_Context = nullptr;
Poco::Util::Timer g_CronJobsTimer;
EmailAccount g_EmailAccount;
int g_SessionTimeout = SESSION_TIMEOUT_DEFAULT;
std::string g_serverPath;

View File

@ -6,6 +6,7 @@
#include "Poco/Util/LayeredConfiguration.h"
#include "Poco/Net/Context.h"
#include "Poco/Types.h"
#include "Poco/Util/Timer.h"
#include "tasks/CPUSheduler.h"
@ -48,6 +49,7 @@ namespace ServerConfig {
extern UniLib::controller::CPUSheduler* g_CPUScheduler;
extern UniLib::controller::CPUSheduler* g_CryptoCPUScheduler;
extern Poco::Net::Context::Ptr g_SSL_CLient_Context;
extern Poco::Util::Timer g_CronJobsTimer;
extern EmailAccount g_EmailAccount;
extern int g_SessionTimeout;
extern std::string g_serverPath;

View File

@ -3,8 +3,15 @@
#include "sodium.h"
#include "../SingletonManager/SessionManager.h"
#include "../SingletonManager/ErrorManager.h"
#include "../lib/DataTypeConverter.h"
#include "../tasks/VerificationEmailResendTask.h"
#include "../ServerConfig.h"
#include "Poco/Timestamp.h"
namespace controller {
User::User(model::table::User* dbModel)
@ -224,4 +231,54 @@ namespace controller {
return result;
}
int User::checkIfVerificationEmailsShouldBeResend(const Poco::Util::Timer& timer)
{
auto cm = ConnectionManager::getInstance();
auto em = ErrorManager::getInstance();
static const char* function_name = "User::checkIfVerificationEmailsShouldBeResend";
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select(session);
std::vector<Poco::Tuple<int,Poco::DateTime>> results;
select << "select u.id, v.created from users as u "
<< "LEFT JOIN email_opt_in as v ON(u.id = v.user_id) "
<< "where u.email_checked = 0 "
<< "AND v.resend_count <= 1", Poco::Data::Keywords::into(results)
;
try {
auto now = Poco::DateTime();
select.execute();
int count_scheduled_at_once = 0;
int count_scheduled = 0;
for (auto it = results.begin(); it != results.end(); it++) {
auto user_id = it->get<0>();
auto created = it->get<1>();
auto age = now - created;
// older than 7 days, schedule at once
if (age.days() > 7) {
UniLib::controller::TaskPtr verificationResendTask(new VerificationEmailResendTask(user_id));
verificationResendTask->scheduleTask(verificationResendTask);
count_scheduled_at_once++;
}
// younger than 7 days, schedule for created + 7 days
else {
auto runDateTime = created + Poco::Timespan(7, 0, 0, 0, 0);
ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(runDateTime.microsecond()));
count_scheduled++;
}
}
if(count_scheduled_at_once) printf("scheduled %d verification email resend at once\n", count_scheduled_at_once);
if(count_scheduled) printf("scheduled %d verification email resend in the next 7 days\n", count_scheduled);
}
catch (Poco::Exception& ex) {
em->addError(new ParamError(function_name, "mysql error by select", ex.displayText().data()));
em->sendErrorsAsEmail();
return -1;
}
return 0;
}
}

View File

@ -29,7 +29,16 @@ namespace controller {
static std::vector<User*> search(const std::string& searchString);
//! \brief go through whole db and search users with email_checked = false and schedule resend 7 days after email_opt_in created date
//!
//! Should be only called by server start, later it aren't necessary, because register function schedule resend tasks by himself.
//! By users which has registered long time ago and haven't activated there account and haven't get a second email send verification email with duration at once
// TODO: instead scheduling all, scheduling only for next day and run this function every day (own task for that)
static int checkIfVerificationEmailsShouldBeResend(const Poco::Util::Timer& timer);
inline size_t load(const std::string& email) { return getModel()->loadFromDB("email", email); }
//! \brief try to load user from db via user_id
//! \return count of found rows, should be 1 or 0
inline size_t load(int user_id) { return getModel()->loadFromDB("id", user_id); }
int load(const unsigned char* pubkey_array);
Poco::JSON::Object getJson();

View File

@ -16,6 +16,7 @@
#include "../tasks/SendEmailTask.h"
#include "../tasks/SigningTransaction.h"
#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h"
#include "../tasks/VerificationEmailResendTask.h"
#include "../lib/JsonRequest.h"
@ -389,6 +390,9 @@ bool Session::createUserDirect(const std::string& first_name, const std::string&
auto email_verification = controller::EmailVerificationCode::create(user_id, model::table::EMAIL_OPT_IN_REGISTER_DIRECT);
email_verification->getModel()->insertIntoDB(false);
auto _7days_later = Poco::DateTime() + Poco::Timespan(7, 0, 0, 0, 0);
ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(_7days_later.microsecond()));
email_manager->addEmail(new model::Email(email_verification, mNewUser, model::EMAIL_USER_VERIFICATION_CODE));
return true;