remove errors, restructure

This commit is contained in:
Dario 2020-01-08 14:49:58 +01:00
parent 5842f21e89
commit c2c4071180
18 changed files with 308 additions and 165 deletions

View File

@ -36,59 +36,24 @@ void ConfigPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:
#line 9 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( pageName );
responseStream << "</title>\n";
responseStream << "<!--<link rel=\"stylesheet\" type=\"text/css\" href=\"css/styles.min.css\">-->\n";
responseStream << "<link rel=\"stylesheet\" type=\"text/css\" href=\"";
#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "/css/styles.css\">\n";
responseStream << "<style type=\"text/css\" >\n";
responseStream << ".grd_container\n";
responseStream << "{\n";
responseStream << " max-width:820px;\n";
responseStream << " margin-left:auto;\n";
responseStream << " margin-right:auto;\n";
responseStream << "}\n";
responseStream << "\n";
responseStream << "input:not([type='radio']) {\n";
responseStream << "\twidth:200px;\n";
responseStream << "}\n";
responseStream << "label:not(.grd_radio_label) {\n";
responseStream << "\twidth:80px;\n";
responseStream << "\tdisplay:inline-block;\n";
responseStream << "}\n";
responseStream << ".grd_container_small\n";
responseStream << "{\n";
responseStream << " max-width:500px;\n";
responseStream << "}\n";
responseStream << ".grd_text {\n";
responseStream << " max-width:550px;\n";
responseStream << " margin-bottom: 5px;\n";
responseStream << "}\n";
responseStream << ".dev-info {\n";
responseStream << "\tposition: fixed;\n";
responseStream << "\tcolor:grey;\n";
responseStream << "\tfont-size: smaller;\n";
responseStream << "\tleft:8px;\n";
responseStream << "}\n";
responseStream << ".grd-time-used { \n";
responseStream << " bottom:0;\n";
responseStream << "} \n";
responseStream << "\n";
responseStream << ".versionstring {\n";
responseStream << "\ttop:0;\n";
responseStream << "}\n";
responseStream << "</style>\n";
responseStream << "css/loginServer/style.css\">\n";
responseStream << "</head>\n";
responseStream << "<body>\n";
responseStream << "<body class=\"header-fixed\">\n";
responseStream << "<div class=\"versionstring dev-info\">\n";
responseStream << "\t<p class=\"grd_small\">Login Server in Entwicklung</p>\n";
responseStream << "\t<p class=\"grd_small\">Alpha 0.6.0</p>\n";
responseStream << "\t<p class=\"grd_small\">Alpha ";
#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_versionString );
responseStream << "</p>\n";
responseStream << "</div>\n";
responseStream << "<!--<nav class=\"grd-left-bar expanded\" data-topbar role=\"navigation\">\n";
responseStream << "\t<div class=\"grd-left-bar-section\">\n";
responseStream << "\t\t<ul class=\"grd-no-style\">\n";
responseStream << "\t\t <li><a href=\"";
#line 58 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
#line 20 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "\" class=\"grd-nav-bn\">Startseite</a>\n";
responseStream << "\t\t <li><a href=\"./account/logout\" class=\"grd-nav-bn\">Logout</a></li>\n";

View File

@ -167,6 +167,7 @@ bool HandleElopageRequestTask::validateInput()
void HandleElopageRequestTask::writeUserIntoDB()
{
printf("HandleElopageRequestTask::writeUserIntoDB\n");
auto cm = ConnectionManager::getInstance();
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement insert(session);
@ -187,9 +188,9 @@ int HandleElopageRequestTask::getUserIdFromDB()
auto cm = ConnectionManager::getInstance();
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select(session);
int user_id = 0;
std::vector<int> user_ids;
select << "SELECT id from users where email = ?;",
into(user_id), use(mEmail);
into(user_ids), use(mEmail);
try {
select.execute();
}
@ -197,8 +198,25 @@ int HandleElopageRequestTask::getUserIdFromDB()
addError(new ParamError(__FUNCTION__, "mysql error selecting from db", ex.displayText().data()));
addError(new ParamError(__FUNCTION__, "email: ", mEmail.data()));
}
if (user_ids.size() > 1) {
std::string duplicateIds("duplicate user ids for email: ");
duplicateIds += mEmail;
duplicateIds += ": ";
for (int i = 0; i < user_ids.size(); i++) {
if (i > 0) {
duplicateIds += ", ";
}
duplicateIds += std::to_string(user_ids[i]);
}
addError(new Error("HandleElopageRequestTask::getUserIdFromDB", duplicateIds.data()));
sendErrorsAsEmail();
}
if (user_ids.size() >= 1) {
return user_ids[0];
}
return 0;
return user_id;
}
@ -207,7 +225,7 @@ int HandleElopageRequestTask::run()
// get input data
// check event type
std::string event = mRequestData.get("event", "");
if (event == "lesson.viewed") {
if (event == "lesson.viewed" || event == "lesson.completed") {
return 0;
}

View File

@ -116,7 +116,10 @@ void RegisterPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Ne
responseStream << "<body>\n";
responseStream << "<div class=\"versionstring dev-info\">\n";
responseStream << "\t<p class=\"grd_small\">Login Server in Entwicklung</p>\n";
responseStream << "\t<p class=\"grd_small\">Alpha 0.8.1</p>\n";
responseStream << "\t<p class=\"grd_small\">Alpha ";
#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp"
responseStream << ( ServerConfig::g_versionString );
responseStream << "</p>\n";
responseStream << "</div>\n";
responseStream << "<!--<nav class=\"grd-left-bar expanded\" data-topbar role=\"navigation\">\n";
responseStream << "\t<div class=\"grd-left-bar-section\">\n";

View File

@ -30,7 +30,7 @@ public:
inline void setConnection(std::string connectionString, ConnectionType type) {
if (type == CONNECTION_MYSQL_LOGIN_SERVER || CONNECTION_MYSQL_PHP_SERVER) {
mSessionPoolNames[type] = Poco::Data::Session::uri(Poco::Data::MySQL::Connector::KEY, connectionString);
mSessionPools.add(Poco::Data::MySQL::Connector::KEY, connectionString);
mSessionPools.add(Poco::Data::MySQL::Connector::KEY, connectionString, 1, 16);
//mConnectionData[type] = connectionString;
}
}

View File

@ -121,6 +121,7 @@ int SessionManager::generateNewUnusedHandle()
Session* SessionManager::getNewSession(int* handle)
{
const static char* functionName = "SessionManager::getNewSession";
if (!mInitalized) {
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
return nullptr;
@ -134,7 +135,7 @@ Session* SessionManager::getNewSession(int* handle)
Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500);
}
catch (Poco::TimeoutException &ex) {
printf("[SessionManager::getNewSession] exception timout mutex: %s\n", ex.displayText().data());
printf("[%s] exception timout mutex: %s\n", functionName, ex.displayText().data());
return nullptr;
}
//mWorkingMutex.lock();
@ -165,7 +166,8 @@ Session* SessionManager::getNewSession(int* handle)
}
else {
ErrorList errors;
errors.addError(new Error("SessionManager::getNewSession", "found dead locked session, keeping in memory without reference"));
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();
mRequestSessionMap.erase(local_handle);

View File

@ -31,18 +31,59 @@ namespace controller {
{
auto code = createEmailVerificationCode();
auto db = new model::table::EmailOptIn(code, user_id, type);
auto result = new EmailVerificationCode(db);
return Poco::AutoPtr<EmailVerificationCode>(result);
return Poco::AutoPtr<EmailVerificationCode>(new EmailVerificationCode(db));
}
Poco::AutoPtr<EmailVerificationCode> EmailVerificationCode::create(model::table::EmailOptInType type/* = EMAIL_OPT_IN_REGISTER*/)
{
auto code = createEmailVerificationCode();
auto db = new model::table::EmailOptIn(code, type);
auto result = new EmailVerificationCode(db);
return Poco::AutoPtr<EmailVerificationCode>(result);
return Poco::AutoPtr<EmailVerificationCode>(new EmailVerificationCode(db));
}
Poco::AutoPtr<EmailVerificationCode> EmailVerificationCode::load(Poco::UInt64 code)
{
auto db = new model::table::EmailOptIn();
if (db->loadFromDB("verification_code", code) == 1) {
return Poco::AutoPtr<EmailVerificationCode>(new EmailVerificationCode(db));
}
db->release();
return nullptr;
}
Poco::AutoPtr<EmailVerificationCode> EmailVerificationCode::load(int user_id, model::table::EmailOptInType type) {
auto db = new model::table::EmailOptIn();
std::vector<std::string> fields = { "user_id", "email_opt_in_type_id" };
if (db->loadFromDB(fields, user_id, (int)type) == 1) {
return Poco::AutoPtr<EmailVerificationCode>(new EmailVerificationCode(db));
}
db->release();
return nullptr;
}
std::vector<Poco::AutoPtr<EmailVerificationCode>> EmailVerificationCode::load(int user_id)
{
auto db = new model::table::EmailOptIn();
auto results = db->loadFromDB<int, model::table::EmailOptInTuple>("user_id", user_id, 2);
std::vector<Poco::AutoPtr<EmailVerificationCode>> resultObjects;
if (db->errorCount()) {
db->sendErrorsAsEmail();
db->release();
return resultObjects;
}
db->release();
if (results.size() == 0) {
return resultObjects;
}
for (auto it = results.begin(); it != results.end(); it++) {
resultObjects.push_back(new EmailVerificationCode(new model::table::EmailOptIn(*it)));
}
return resultObjects;
}
Poco::UInt64 EmailVerificationCode::createEmailVerificationCode()
{
Poco::UInt64 resultCode;

View File

@ -14,11 +14,11 @@ namespace controller {
static Poco::AutoPtr<EmailVerificationCode> create(int user_id, model::table::EmailOptInType type = model::table::EMAIL_OPT_IN_REGISTER);
static Poco::AutoPtr<EmailVerificationCode> create(model::table::EmailOptInType type = model::table::EMAIL_OPT_IN_REGISTER);
inline size_t load(Poco::UInt64 code) { return getModel()->loadFromDB("verification_code", code); }
inline size_t load(int user_id, model::table::EmailOptInType type) {
std::vector<std::string> fields = { "user_id", "email_opt_in_type_id"};
return getModel()->loadFromDB(fields, user_id, (int)type);
}
static Poco::AutoPtr<EmailVerificationCode> load(Poco::UInt64 code);
static std::vector<Poco::AutoPtr<EmailVerificationCode>> load(int user_id);
static Poco::AutoPtr<EmailVerificationCode> load(int user_id, model::table::EmailOptInType type);
inline Poco::AutoPtr<model::table::EmailOptIn> getModel() { return _getModel<model::table::EmailOptIn>(); }
std::string getLink();

View File

@ -8,7 +8,6 @@ namespace controller {
User::~User()
{
}

View File

@ -47,6 +47,8 @@ namespace UniLib {
bool tryLock();
inline void unlock() { mLastSucceededLock = ""; mWorkMutex.unlock(); }
inline const std::string& getLastSucceededLock() { return mLastSucceededLock; }
protected:
private:
Poco::Mutex mWorkMutex;

View File

@ -8,6 +8,9 @@
#include "lib/Profiler.h"
#include "ServerConfig.h"
#include "model/table/User.h"
#include "model/table/EmailOptIn.h"
#ifndef _TEST_BUILD
@ -21,6 +24,7 @@ int main(int argc, char** argv)
}
ServerConfig::g_versionString = "0.10.1";
printf("User size: %d Bytes, Session size: %d Bytes\n", sizeof(User), sizeof(Session));
printf("model sizes: User: %d Bytes, EmailOptIn: %d Bytes\n", sizeof(model::table::User), sizeof(model::table::EmailOptIn));
// first check time for crypto
auto testUser = new User("email@google.de", "Max", "Mustermann");

View File

@ -18,6 +18,7 @@
#include "../lib/JsonRequest.h"
#include "../controller/User.h"
#include "../controller/EmailVerificationCode.h"
#include "table/ModelBase.h"
@ -28,27 +29,16 @@ using namespace Poco::Data::Keywords;
int WriteEmailVerification::run()
{
Profiler timeUsed;
auto em = ErrorManager::getInstance();
//printf("[WriteEmailVerification::run] E-Mail Verification Code: %llu\n", verificationCode);
auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
//int user_id = mUser->getDBId();
Poco::Data::Statement insert(dbSession);
insert << "INSERT INTO email_opt_in (user_id, verification_code) VALUES(?,?);",
bind(mUser->getDBId()), use(mEmailVerificationCode);
try {
if (1 != insert.execute()) {
em->addError(new Error("[WriteEmailVerification]", "error inserting email verification code"));
em->sendErrorsAsEmail();
return -1;
}
} catch (Poco::Exception& ex) {
em->addError(new ParamError("[WriteEmailVerification]", "error inserting email verification code", ex.displayText().data()));
em->sendErrorsAsEmail();
return -2;
mEmailVerificationCode->getModel()->setUserId(mUser->getDBId());
auto emailVerificationModel = mEmailVerificationCode->getModel();
emailVerificationModel->setUserId(mUser->getDBId());
if (!emailVerificationModel->insertIntoDB() || emailVerificationModel->errorCount() > 0) {
emailVerificationModel->sendErrorsAsEmail();
return -1;
}
//printf("[WriteEmailVerification] timeUsed: %s\n", timeUsed.string().data());
return 0;
}
@ -89,7 +79,7 @@ int WritePassphraseIntoDB::run()
// --------------------------------------------------------------------------------------------------------------
Session::Session(int handle)
: mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mState(SESSION_STATE_EMPTY), mActive(false)
: mHandleId(handle), mSessionUser(nullptr), mState(SESSION_STATE_EMPTY), mActive(false)
{
}
@ -122,7 +112,7 @@ void Session::reset()
mPassphrase = "";
mClientLoginIP = Poco::Net::IPAddress();
mEmailVerificationCode = 0;
mEmailVerificationCodeObject = nullptr;
unlock();
//printf("[Session::reset] finished\n");
}
@ -207,14 +197,14 @@ bool Session::createUser(const std::string& first_name, const std::string& last_
writeUserIntoDB->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_USER_WRITTEN, this));
writeUserIntoDB->scheduleTask(writeUserIntoDB);
createEmailVerificationCode();
auto emailVerificationCodeObject = controller::EmailVerificationCode::create();
emailVerificationCodeObject->getModel()->setCode(mEmailVerificationCode);
UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, mEmailVerificationCode, ServerConfig::g_CPUScheduler, 1));
mEmailVerificationCodeObject = controller::EmailVerificationCode::create(model::table::EMAIL_OPT_IN_REGISTER);
UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, mEmailVerificationCodeObject, ServerConfig::g_CPUScheduler, 1));
writeEmailVerification->setParentTaskPtrInArray(writeUserIntoDB, 0);
writeEmailVerification->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, this));
writeEmailVerification->scheduleTask(writeEmailVerification);
/*printf("LastName: %s\n", last_name.data());
for (int i = 0; i < last_name.size(); i++) {
@ -247,7 +237,7 @@ bool Session::createUser(const std::string& first_name, const std::string& last_
*/
//UniLib::controller::TaskPtr sendEmail(new SendEmailTask(message, ServerConfig::g_CPUScheduler, 1));
//Email(AutoPtr<controller::EmailVerificationCode> emailVerification, AutoPtr<controller::User> user, EmailType type);
UniLib::controller::TaskPtr sendEmail(new SendEmailTask(new model::Email(emailVerificationCodeObject, mNewUser, model::EMAIL_USER_VERIFICATION_CODE), ServerConfig::g_CPUScheduler, 1));
UniLib::controller::TaskPtr sendEmail(new SendEmailTask(new model::Email(mEmailVerificationCodeObject, mNewUser, model::EMAIL_USER_VERIFICATION_CODE), ServerConfig::g_CPUScheduler, 1));
//sendEmail->setParentTaskPtrInArray(prepareEmail, 0);
sendEmail->setParentTaskPtrInArray(writeEmailVerification, 0);
sendEmail->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_SEND, this));
@ -290,7 +280,7 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
Profiler usedTime;
auto em = ErrorManager::getInstance();
if(mEmailVerificationCode == emailVerificationCode) {
if(getEmailVerificationCode() == emailVerificationCode) {
if (mSessionUser && mSessionUser->getDBId() == 0) {
//addError(new Error("E-Mail Verification", "Benutzer wurde nicht richtig gespeichert, bitte wende dich an den Server-Admin"));
em->addError(new Error(funcName, "user exist with 0 as id"));
@ -395,6 +385,7 @@ int Session::resetPassword(Poco::AutoPtr<controller::User> user, bool passphrase
return 1;
}
auto emailVerificationModel = mEmailVerificationCodeObject->getModel();
UniLib::controller::TaskPtr insertEmailVerificationCode(
new model::table::ModelInsertTask(emailVerificationModel, true)
);
@ -629,28 +620,38 @@ void Session::detectSessionState()
}
UserStates userState = mSessionUser->getUserState();
/*
if (mSessionUser->getDBId() == 0) {
updateState(SESSION_STATE_CRYPTO_KEY_GENERATED);
return;
}*/
int checkEmail = -1, resetPasswd = -1;
try {
auto emailVerificationCodeObjects = controller::EmailVerificationCode::load(mSessionUser->getDBId());
for (int i = 0; i < emailVerificationCodeObjects.size(); i++) {
auto type = emailVerificationCodeObjects[i]->getModel()->getType();
if (type == model::table::EMAIL_OPT_IN_EMPTY || type == model::table::EMAIL_OPT_IN_REGISTER) {
checkEmail = i;
}
else if (type == model::table::EMAIL_OPT_IN_RESET_PASSWORD) {
resetPasswd = i;
}
}
if (resetPasswd != -1) {
mEmailVerificationCodeObject = emailVerificationCodeObjects[resetPasswd];
}
else if (checkEmail != -1) {
mEmailVerificationCodeObject = emailVerificationCodeObjects[checkEmail];
}
}
catch (Poco::Exception& ex) {
printf("[Session::detectSessionState] exception: %s\n", ex.displayText().data());
//return;
}
if (userState <= USER_EMAIL_NOT_ACTIVATED) {
if (mEmailVerificationCode == 0) {
auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select(dbConnection);
auto user_id = mSessionUser->getDBId();
select << "SELECT verification_code from email_opt_in where user_id = ?",
into(mEmailVerificationCode), use(user_id);
try {
if (select.execute() == 1) {
updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN);
return;
}
}
catch (Poco::Exception& ex) {
printf("[Session::detectSessionState] mysql exception: %s\n", ex.displayText().data());
}
if (checkEmail != -1) {
updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN);
return;
}
updateState(SESSION_STATE_USER_WRITTEN);
@ -681,9 +682,14 @@ void Session::detectSessionState()
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
return;
}
updateState(SESSION_STATE_KEY_PAIR_WRITTEN);
if (resetPasswd != -1) {
updateState(SESSION_STATE_RESET_PASSWORD_REQUEST);
return;
}
}
Poco::Net::HTTPCookie Session::getLoginCookie()
@ -703,49 +709,42 @@ Poco::Net::HTTPCookie Session::getLoginCookie()
bool Session::loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode)
{
Profiler usedTime;
const static char* funcName = "Session::loadFromEmailVerificationCode";
auto em = ErrorManager::getInstance();
auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select(dbConnection);
std::string email, first_name, last_name;
int user_id = 0;
select.reset(dbConnection);
select << "SELECT user_id FROM email_opt_in WHERE verification_code=?",
into(user_id), use(emailVerificationCode);
try {
size_t rowCount = select.execute();
if (rowCount != 1) {
em->addError(new ParamError(funcName, "select user by email verification code work not like expected, selected row count", rowCount));
em->addError(new ParamError(funcName, "emailVerficiation Code: ", std::to_string(emailVerificationCode)));
em->sendErrorsAsEmail();
}
if (rowCount < 1) {
addError(new Error(gettext("E-Mail Verification"), gettext("Konnte keinen passenden Account finden.")));
return false;
}
mSessionUser = new User(user_id);
mSessionUser->setLanguage(getLanguage());
mEmailVerificationCodeObject = controller::EmailVerificationCode::load(emailVerificationCode);
if (mEmailVerificationCodeObject.isNull()) {
addError(new Error(gettext("E-Mail Verification"), gettext("Konnte kein passendes Konto finden.")));
return false;
}
mEmailVerificationCode = emailVerificationCode;
mNewUser = controller::User::create();
mNewUser->load(mEmailVerificationCodeObject->getModel()->getUserId());
if (mNewUser->getModel()->errorCount() > 0) {
mNewUser->getModel()->sendErrorsAsEmail();
addError(new Error(gettext("E-Mail Verification"), gettext("Fehler beim laden des Benutzers.")));
return false;
}
mSessionUser = new User(mNewUser);
mSessionUser->setLanguage(getLanguage());
auto verificationType = mEmailVerificationCodeObject->getModel()->getType();
if (verificationType == model::table::EMAIL_OPT_IN_RESET_PASSWORD) {
updateState(SESSION_STATE_RESET_PASSWORD_REQUEST);
}
else {
updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN);
//printf("[Session::loadFromEmailVerificationCode] time: %s\n", usedTime.string().data());
return true;
}
catch (const Poco::Exception& ex) {
em->addError(new ParamError(funcName, "exception selecting user from verification code", ex.displayText().data()));
em->addError(new ParamError(funcName, "emailVerficiation Code: ", std::to_string(emailVerificationCode)));
em->sendErrorsAsEmail();
}
return false;
return true;
}
void Session::updateState(SessionStates newState)
{
lock("Session::updateState");
if (!mActive) return;
if (!mActive) {
unlock();
return;
}
updateTimeout();
//printf("[%s] newState: %s\n", __FUNCTION__, translateSessionStateToString(newState));
if (newState > mState) {
@ -785,14 +784,7 @@ const char* Session::translateSessionStateToString(SessionStates state)
return "error";
}
void Session::createEmailVerificationCode()
{
uint32_t* code_p = (uint32_t*)&mEmailVerificationCode;
for (int i = 0; i < sizeof(mEmailVerificationCode) / 4; i++) {
code_p[i] = randombytes_random();
}
}
/*
bool Session::useOrGeneratePassphrase(const std::string& passphase)
{

View File

@ -44,6 +44,7 @@ enum SessionStates {
SESSION_STATE_PASSPHRASE_WRITTEN,
SESSION_STATE_KEY_PAIR_GENERATED,
SESSION_STATE_KEY_PAIR_WRITTEN,
SESSION_STATE_RESET_PASSWORD_REQUEST,
SESSION_STATE_COUNT
};
@ -118,7 +119,7 @@ public:
const char* getSessionStateString();
inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; }
inline Poco::UInt64 getEmailVerificationCode() { return mEmailVerificationCode; }
inline Poco::UInt64 getEmailVerificationCode() { if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode(); }
inline bool isActive() { bool bret = false; lock("Session::isActive"); bret = mActive; unlock(); return bret; }
inline void setActive(bool active) { lock("Sessions::setActive"); mActive = active; unlock(); }
@ -142,8 +143,6 @@ protected:
void updateTimeout();
inline void setHandle(int newHandle) { mHandleId = newHandle; }
void createEmailVerificationCode();
void detectSessionState();
static const char* translateSessionStateToString(SessionStates state);
@ -156,7 +155,6 @@ private:
std::string mPassphrase;
Poco::DateTime mLastActivity;
Poco::Net::IPAddress mClientLoginIP;
Poco::UInt64 mEmailVerificationCode;
Poco::AutoPtr<controller::EmailVerificationCode> mEmailVerificationCodeObject;
@ -173,7 +171,7 @@ private:
class WriteEmailVerification : public UniLib::controller::CPUTask
{
public:
WriteEmailVerification(Poco::AutoPtr<User> user, Poco::UInt64 emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0)
WriteEmailVerification(Poco::AutoPtr<User> user, Poco::AutoPtr<controller::EmailVerificationCode> 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());
@ -185,7 +183,7 @@ public:
private:
Poco::AutoPtr<User> mUser;
Poco::UInt64 mEmailVerificationCode;
Poco::AutoPtr<controller::EmailVerificationCode> mEmailVerificationCode;
};

View File

@ -89,16 +89,20 @@ int UserWriteIntoDB::run()
// --------------------------------------------------------------------------------------------------------
UserWriteKeysIntoDB::UserWriteKeysIntoDB(UniLib::controller::TaskPtr parent, Poco::AutoPtr<User> user, bool savePrivKey)
: UniLib::controller::CPUTask(1), mUser(user), mSavePrivKey(savePrivKey)
UserWriteKeysIntoDB::UserWriteKeysIntoDB(std::vector<UniLib::controller::TaskPtr> parents, Poco::AutoPtr<User> user, bool savePrivKey)
: UniLib::controller::CPUTask(parents.size()), mUser(user), mSavePrivKey(savePrivKey)
{
#ifdef _UNI_LIB_DEBUG
setName(user->getEmail());
#endif
if (strcmp(parent->getResourceType(), "UserGenerateKeys") != 0) {
if (parents.size() < 1 || strcmp(parents[0]->getResourceType(), "UserGenerateKeys") != 0) {
throw Poco::Exception("given TaskPtr isn't UserGenerateKeys");
}
setParentTaskPtrInArray(parent, 0);
for (int i = 0; i < parents.size(); i++) {
setParentTaskPtrInArray(parents[i], i);
}
//setParentTaskPtrInArray(parents[0], 0);
}
int UserWriteKeysIntoDB::run()
@ -372,6 +376,42 @@ User::User(const unsigned char* pubkey_array)
}
}
User::User(Poco::AutoPtr<controller::User> ctrl_user)
: mUserCtrl(ctrl_user), mState(USER_EMPTY), mDBId(0), mPasswordHashed(0), mPrivateKey(nullptr), mEmailChecked(false),
mLanguage(LANG_DE), mGradidoCurrentBalance(0), mCryptoKey(nullptr), mReferenceCount(1)
{
assert(!ctrl_user.isNull());
auto model = ctrl_user->getModel();
assert(model);
auto mm = MemoryManager::getInstance();
mDBId = model->getID();
mEmail = model->getEmail();
mFirstName = model->getFirstName();
mLastName = model->getLastName();
mPasswordHashed = model->getPasswordHashed();
auto pubkey = model->getPublicKey();
if (pubkey) {
memcpy(mPublicKey, pubkey, crypto_sign_PUBLICKEYBYTES);
size_t hexSize = crypto_sign_PUBLICKEYBYTES * 2 + 1;
auto hexStringTemp = mm->getFreeMemory(hexSize);
//char* hexString = (char*)malloc(hexSize);
memset(*hexStringTemp, 0, hexSize);
sodium_bin2hex(*hexStringTemp, hexSize, pubkey, crypto_sign_PUBLICKEYBYTES);
mPublicHex = *hexStringTemp;
mm->releaseMemory(hexStringTemp);
}
if (model->existPrivateKeyCrypted()) {
auto privKeyVetor = model->getPrivateKeyCrypted();
mPrivateKey = mm->getFreeMemory(privKeyVetor.size());
memcpy(*mPrivateKey, privKeyVetor.data(), privKeyVetor.size());
}
mEmailChecked = model->isEmailChecked();
mLanguage = LanguageManager::languageFromString(model->getLanguageKey());
mLanguageCatalog = LanguageManager::getInstance()->getFreeCatalog(mLanguage);
}
User::~User()
{
@ -767,7 +807,14 @@ bool User::generateKeys(bool savePrivkey, const std::string& passphrase, Session
}
duplicate();
UniLib::controller::TaskPtr saveKeysTask(new UserWriteKeysIntoDB(generateKeysTask, this, savePrivkey));
std::vector<UniLib::controller::TaskPtr> parentsForWriteKeys;
parentsForWriteKeys.reserve(2);
parentsForWriteKeys.push_back(generateKeysTask);
if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) {
parentsForWriteKeys.push_back(mCreateCryptoKeyTask);
}
UniLib::controller::TaskPtr saveKeysTask(new UserWriteKeysIntoDB(parentsForWriteKeys, this, savePrivkey));
saveKeysTask->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_KEY_PAIR_WRITTEN, session));
saveKeysTask->scheduleTask(saveKeysTask);

View File

@ -15,6 +15,8 @@
#include "../SingletonManager/MemoryManager.h"
#include "../SingletonManager/LanguageManager.h"
#include "../controller/User.h"
class UserCreateCryptoKey;
class UserWriteIntoDB;
class Session;
@ -61,6 +63,10 @@ public:
User(const unsigned char* pubkey_array);
User(int user_id);
// load from controller user
User(Poco::AutoPtr<controller::User> ctrl_user);
// login
//User(const std::string& email, const std::string& password);
@ -136,6 +142,7 @@ protected:
bool setPrivKey(const MemoryBin* privKey);
private:
Poco::AutoPtr<controller::User> mUserCtrl;
UserStates mState;
// ************************* DB FIELDS ******************************
@ -232,7 +239,7 @@ private:
class UserWriteKeysIntoDB : public UniLib::controller::CPUTask
{
public:
UserWriteKeysIntoDB(UniLib::controller::TaskPtr parent, Poco::AutoPtr<User> user, bool savePrivKey);
UserWriteKeysIntoDB(std::vector<UniLib::controller::TaskPtr> parents, Poco::AutoPtr<User> user, bool savePrivKey);
virtual int run();

View File

@ -24,6 +24,12 @@ namespace model {
}
EmailOptIn::EmailOptIn(const EmailOptInTuple& tuple)
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mEmailVerificationCode(tuple.get<2>()), mType(tuple.get<3>())
{
}
EmailOptIn::~EmailOptIn()
{
@ -56,6 +62,17 @@ namespace model {
return select;
}
Poco::Data::Statement EmailOptIn::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName)
{
Poco::Data::Statement select(session);
select << "SELECT id, user_id, verification_code, email_opt_in_type_id FROM " << getTableName()
<< " where " << fieldName << " = ?";
return select;
}
Poco::Data::Statement EmailOptIn::_loadFromDB(Poco::Data::Session session, const std::vector<std::string>& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/)
{
Poco::Data::Statement select(session);

View File

@ -5,20 +5,25 @@
#include "ModelBase.h"
#include "Poco/Types.h"
#include "Poco/Tuple.h"
namespace model {
namespace table {
enum EmailOptInType {
EMAIL_OPT_IN_EMPTY = 0,
EMAIL_OPT_IN_REGISTER = 1,
EMAIL_OPT_IN_RESET_PASSWORD = 2
};
typedef Poco::Tuple<int, int, Poco::UInt64, int> EmailOptInTuple;
class EmailOptIn : public ModelBase
{
public:
EmailOptIn(const Poco::UInt64& code, int user_id, EmailOptInType type);
EmailOptIn(const Poco::UInt64& code, EmailOptInType type);
EmailOptIn(const EmailOptInTuple& tuple);
EmailOptIn();
~EmailOptIn();
@ -27,17 +32,21 @@ namespace model {
std::string toString();
inline Poco::UInt64 getCode() const { return mEmailVerificationCode; }
inline int getUserId() const { return mUserId; }
inline EmailOptInType getType() const { return static_cast<EmailOptInType>(mType);}
inline void setCode(Poco::UInt64 code) { mEmailVerificationCode = code; }
inline void setUserId(int user_Id) { mUserId = user_Id; }
static const char* typeToString(EmailOptInType type);
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::vector<std::string>& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
int mUserId;
// data type must be a multiple of 4
Poco::UInt64 mEmailVerificationCode;
int mUserId;
int mType;
};

View File

@ -40,6 +40,7 @@ namespace model {
bool ModelBase::insertIntoDB()
{
printf("ModelBase::insertIntoDB with table: %s\n", getTableName());
auto cm = ConnectionManager::getInstance();
Poco::Data::Statement insert = _insertIntoDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
@ -87,6 +88,13 @@ namespace model {
throw Poco::Exception(message);
}
Poco::Data::Statement ModelBase::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName)
{
std::string message = getTableName();
message += "::_loadMultipleFromDB not implemented";
throw Poco::Exception(message);
}
Poco::DateTime ModelBase::parseElopageDate(std::string dateString)
{
std::string decodedDateString = "";

View File

@ -29,9 +29,14 @@ namespace model {
virtual const char* getTableName() = 0;
virtual std::string toString() = 0;
template<class T> size_t updateIntoDB(const std::string& fieldName, const T& fieldValue );
template<class T> size_t loadFromDB(const std::string& fieldName, const T& fieldValue);
template<class T1, class T2> size_t loadFromDB(const std::vector<std::string>& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
template<class T>
size_t updateIntoDB(const std::string& fieldName, const T& fieldValue );
template<class T>
size_t loadFromDB(const std::string& fieldName, const T& fieldValue);
template<class WhereFieldType, class Tuple>
std::vector<Tuple> loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0);
template<class T1, class T2>
size_t loadFromDB(const std::vector<std::string>& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
bool insertIntoDB();
inline void setID(int id) { lock(); mID = id; unlock(); }
@ -46,6 +51,7 @@ namespace model {
virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName) = 0;
virtual Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::vector<std::string>& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
virtual Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName);
virtual Poco::Data::Statement _insertIntoDB(Poco::Data::Session session) = 0;
int mID;
@ -75,6 +81,31 @@ namespace model {
return resultCount;
}
template<class WhereFieldType, class Tuple>
std::vector<Tuple> ModelBase::loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults)
{
printf("ModelBase::loadFromDB multi\n");
std::vector<Tuple> results;
return results;
if (expectedResults > 0) {
results.reserve(expectedResults);
}
auto cm = ConnectionManager::getInstance();
Poco::Data::Statement select = _loadMultipleFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER), fieldName);
select, Poco::Data::Keywords::into(results), Poco::Data::Keywords::useRef(fieldValue);
size_t resultCount = 0;
try {
resultCount = select.execute();
}
catch (Poco::Exception& ex) {
lock();
addError(new ParamError(getTableName(), "mysql error by multi selecting", ex.displayText().data()));
addError(new ParamError(getTableName(), "field name for select: ", fieldName.data()));
unlock();
}
return results;
}
template<class T1, class T2>
size_t ModelBase::loadFromDB(const std::vector<std::string>& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/)