implement task observer

This commit is contained in:
Dario 2020-01-10 17:29:31 +01:00
parent c2c4071180
commit 33927473ad
31 changed files with 973 additions and 135 deletions

View File

@ -47,6 +47,7 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
//DHASH key = DRMakeStringHash(passphrase);
size_t pass_phrase_size = strlen(passphrase);
std::string clearPassphrase = "";
char acBuffer[STR_BUFFER_SIZE]; memset(acBuffer, 0, STR_BUFFER_SIZE);
size_t buffer_cursor = 0;
// get word indices for hmac key
@ -55,6 +56,8 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
if (passphrase[i] == ' ') {
if(buffer_cursor < 3) continue;
if (word_source->isWordExist(acBuffer)) {
clearPassphrase += acBuffer;
clearPassphrase += " ";
word_indices[word_cursor] = word_source->getWordIndex(acBuffer);
}
else {
@ -80,11 +83,15 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
//crypto_auth_hmacsha512_init(&state, (unsigned char*)word_indices, sizeof(word_indices));
sha512_init(&state);
sha512_update(&state, (unsigned char*)word_indices, sizeof(word_indices));
sha512_update(&state, (unsigned char*)passphrase, pass_phrase_size);
sha512_update(&state, (unsigned char*)clearPassphrase.data(), clearPassphrase.size());
//crypto_auth_hmacsha512_update(&state, (unsigned char*)passphrase, pass_phrase_size);
sha512_final(&state, hash);
//crypto_auth_hmacsha512_final(&state, hash);
// debug passphrase
// printf("\passsphrase: <%s>\n", passphrase);
// printf("word_indices: \n%s\n", getHex((unsigned char*)word_indices, sizeof(word_indices)).data());
// printf("passphrase bin: \n%s\n\n", getHex((unsigned char*)passphrase, pass_phrase_size).data());
//ed25519_create_keypair(public_key, private_key, hash);
private_key_t prv_key_t;
@ -132,6 +139,52 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour
return true;
}
std::string KeyPair::filterPassphrase(const std::string& passphrase)
{
std::string filteredPassphrase;
auto passphrase_size = passphrase.size();
for (int i = 0; i < passphrase_size; i++) {
char c = passphrase.data()[i];
// asci 128 even by utf8 (hex)
// 0000 0000 0000 007F
// utf8
if (c > 0x0000007F) {
int additionalUtfByteCount = 0;
filteredPassphrase += c;
if ((c & 0x00000080) == 0x00000080) {
additionalUtfByteCount = 1;
}
else if ((c & 0x00000800) == 0x00000800) {
additionalUtfByteCount = 2;
}
else if ((c & 0x00010000) == 0x00010000) {
additionalUtfByteCount = 3;
}
for (int j = 1; j <= additionalUtfByteCount; j++) {
filteredPassphrase += passphrase.data()[i + j];
i++;
}
}
else {
// 32 = Space
// 65 = A
// 90 = Z
// 97 = a
// 122 = z
if (c == 32 ||
(c >= 65 && c <= 90) ||
(c >= 97 && c <= 122)) {
filteredPassphrase += c;
}
else if (c == '\n' || c == '\r') {
filteredPassphrase += ' ';
}
}
}
return filteredPassphrase;
}
std::string KeyPair::getPubkeyHex()
{
const size_t hexSize = crypto_sign_PUBLICKEYBYTES * 2 + 1;

View File

@ -22,6 +22,7 @@ public:
~KeyPair();
bool generateFromPassphrase(const char* passphrase, Mnemonic* word_source);
static std::string filterPassphrase(const std::string& passphrase);
std::string getPubkeyHex();
bool savePrivKey(int userId);
static std::string getHex(const unsigned char* data, Poco::UInt32 size);

View File

@ -156,6 +156,13 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
return Application::EXIT_CONFIG;
}
// first check time for crypto
auto testUser = new User("email@google.de", "Max", "Mustermann");
Profiler timeUsed;
testUser->validatePwd("haz27Newpassword", nullptr);
ServerConfig::g_FakeLoginSleepTime = (int)std::round(timeUsed.millis());
delete testUser;
Poco::Int64 i1 = randombytes_random();
Poco::Int64 i2 = randombytes_random();
ServerConfig::g_ServerKeySeed->put(1, i1 | (i2 << 8));

View File

@ -28,6 +28,9 @@ void ElopageWebhook::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
//ServerConfig::writeToFile(request.stream(), "elopage_webhook_requests.txt");
// empty response, we didn't need to set anything
//response.setStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT);
std::ostream& _responseStream = response.send();
_responseStream << "200 OK";
std::istream& stream = request.stream();
std::string completeRequest;
@ -234,7 +237,7 @@ int HandleElopageRequestTask::run()
if (elopageBuy->errorCount() > 0) {
getErrors(elopageBuy);
}
UniLib::controller::TaskPtr saveElopageBuy(new model::table::ModelInsertTask(elopageBuy));
UniLib::controller::TaskPtr saveElopageBuy(new model::table::ModelInsertTask(elopageBuy, false));
saveElopageBuy->scheduleTask(saveElopageBuy);
// check product id
@ -342,7 +345,7 @@ int HandleElopageRequestTask::run()
}
// write email verification code into db
UniLib::controller::TaskPtr saveEmailVerificationCode(new model::table::ModelInsertTask(emailVerification->getModel()));
UniLib::controller::TaskPtr saveEmailVerificationCode(new model::table::ModelInsertTask(emailVerification->getModel(), true));
saveEmailVerificationCode->scheduleTask(saveEmailVerificationCode);
int noEMail = 0;

View File

@ -131,8 +131,15 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
}
auto sessionState = s->getSessionState();
printf("session state: %s\n", s->getSessionStateString());
if (url_first_part == "/updateUserPassword" && sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) {
auto pageRequestHandler = new UpdateUserPasswordPage(s);
pageRequestHandler->setProfiler(timeUsed);
return pageRequestHandler;
}
//printf("session state: %s\n", s->getSessionStateString());
if(sessionState == SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED ||
sessionState == SESSION_STATE_PASSPHRASE_GENERATED) {
sessionState == SESSION_STATE_PASSPHRASE_GENERATED ||
sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) {
//if (url_first_part == "/passphrase") {
//return handlePassphrase(s, request);
auto pageRequestHandler = new PassphrasePage(s);
@ -145,6 +152,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
pageRequestHandler->setProfiler(timeUsed);
return pageRequestHandler;
}
else if (sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) {
//
auto pageRequestHandler = new UpdateUserPasswordPage(s);
pageRequestHandler->setProfiler(timeUsed);
return pageRequestHandler;
}
if (url_first_part == "/checkTransactions") {
auto pageRequestHandler = new CheckTransactionPage(s);
pageRequestHandler->setProfiler(timeUsed);
@ -267,10 +280,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
int retUpdateEmailVerification = session->updateEmailVerification(verificationCode);
if (0 == retUpdateEmailVerification) {
printf("[PageRequestHandlerFactory::handleCheckEmail] timeUsed: %s\n", timeUsed.string().data());
//printf("[PageRequestHandlerFactory::handleCheckEmail] timeUsed: %s\n", timeUsed.string().data());
auto pageRequestHandler = new PassphrasePage(session);
pageRequestHandler->setProfiler(timeUsed);
return pageRequestHandler;
}
else if (1 == retUpdateEmailVerification) {
auto user = session->getUser();

View File

@ -8,12 +8,14 @@
#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#include "../SingletonManager/SessionManager.h"
#include "../crypto/KeyPair.h"
//#include "Poco/Net/HTTPServerParams.h"
enum PageState
{
PAGE_ASK_PASSPHRASE,
PAGE_SHOW_PASSPHRASE
PAGE_SHOW_PASSPHRASE,
PAGE_FORCE_ASK_PASSPHRASE
};
#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp"
@ -34,7 +36,7 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
if (_compressResponse) response.set("Content-Encoding", "gzip");
Poco::Net::HTMLForm form(request, request.stream());
#line 17 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 19 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
const char* pageName = "Passphrase";
PageState state = PAGE_ASK_PASSPHRASE;
@ -46,17 +48,33 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
// save login cookie, because maybe we've get an new session
response.addCookie(mSession->getLoginCookie());
if(mSession->getSessionState() == SESSION_STATE_RESET_PASSWORD_REQUEST) {
state = PAGE_FORCE_ASK_PASSPHRASE;
}
if (!form.empty()) {
auto registerKeyChoice = form.get("passphrase", "");
auto registerKeyChoice = form.get("passphrase", "no");
std::string oldPassphrase = "";
if (registerKeyChoice == "no") {
auto oldPassphrase = form.get("passphrase-existing", "");
if (oldPassphrase != "" && User::validatePassphrase(oldPassphrase)) {
auto oldPassphrase = KeyPair::filterPassphrase(form.get("passphrase-existing", ""));
Mnemonic* wordSource = nullptr;
if (oldPassphrase != "" && User::validatePassphrase(oldPassphrase, &wordSource)) {
// passphrase is valid
mSession->setPassphrase(oldPassphrase);
mSession->updateState(SESSION_STATE_PASSPHRASE_SHOWN);
state = PAGE_SHOW_PASSPHRASE;
if(PAGE_FORCE_ASK_PASSPHRASE == state) {
auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, wordSource);
if(-2 == compareResult) {
response.redirect(ServerConfig::g_serverPath + "/error500");
return;
} else if(1 == compareResult) {
response.redirect(ServerConfig::g_serverPath + "/updateUserPassword");
return;
}
} else {
mSession->setPassphrase(oldPassphrase);
mSession->updateState(SESSION_STATE_PASSPHRASE_SHOWN);
state = PAGE_SHOW_PASSPHRASE;
}
}
else {
addError(new Error("Passphrase", "Diese Passphrase ist ung&uuml;ltig, bitte &uuml;berpr&uuml;fen oder neu generieren (lassen)."));
@ -133,7 +151,10 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
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";
@ -151,11 +172,11 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "<div class=\"grd_container\">\n";
responseStream << "\t<h1>Einen neuen Account anlegen</h1>\n";
responseStream << "\t";
#line 57 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 75 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
responseStream << ( getErrorsHtml() );
responseStream << "\n";
responseStream << "\t";
#line 58 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 76 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
if(state == PAGE_SHOW_PASSPHRASE) { responseStream << "\n";
responseStream << "\t\t<div class=\"grd_text-max-width\">\n";
responseStream << "\t\t\t<div class=\"grd_text\">\n";
@ -163,7 +184,7 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t\t\t</div>\n";
responseStream << "\t\t\t<div class=\"grd_textarea\" style=\"width:220px;text-align:center;\">\n";
responseStream << "\t\t\t\t";
#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 82 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
responseStream << ( mSession->getPassphrase() );
responseStream << "\n";
responseStream << "\t\t\t</div>\n";
@ -176,11 +197,11 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t\t\t<a href=\"saveKeys\" class=\"grd-form-bn grd-form-bn-succeed grd_clickable\">Weiter</a>\n";
responseStream << "\t\t</div>\n";
responseStream << "\t";
#line 74 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 92 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
} else if(state == PAGE_ASK_PASSPHRASE) { responseStream << "\n";
responseStream << "\t<p>Deine E-Mail Adresse wurde erfolgreich bestätigt. </p>\n";
responseStream << "\t<form method=\"POST\" action=\"";
#line 76 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 94 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
responseStream << ( uri_start );
responseStream << "/passphrase\">\n";
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
@ -196,7 +217,7 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t\t\t\t<label class=\"grd_radio_label\" for=\"passphrase-new-no\">Ja, bitte wiederherstellen!</label>\n";
responseStream << "\t\t\t</p>\n";
responseStream << "\t\t\t<textarea style=\"width:100%;height:100px\" name=\"passphrase-existing\">";
#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 107 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
responseStream << ( !form.empty() ? form.get("passphrase-existing", "") : "" );
responseStream << "</textarea>\n";
responseStream << "\t\t</fieldset>\n";
@ -205,13 +226,32 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t\t\n";
responseStream << "\t</form>\n";
responseStream << "\t";
#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 113 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
} else if(PAGE_FORCE_ASK_PASSPHRASE == state ) { responseStream << "\n";
responseStream << "\t\t<form method=\"POST\" action=\"";
#line 114 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
responseStream << ( uri_start );
responseStream << "/passphrase\">\n";
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
responseStream << "\t\t\t<legend>Konto wiederherstellen / Neues Passwort anlegen</legend>\n";
responseStream << "\t\t\t<p>Um dein Konto wiederherzustellen, dir ein Neues Passwort ausw&auml;hlen zu können, tippe hier bitte die W&ouml;rter deiner Passphrase in der richtigen Reihenfolge ein, welche du dir aufgeschrieben hast</p>\n";
responseStream << "\t\t\t<textarea style=\"width:100%;height:100px\" name=\"passphrase-existing\">";
#line 118 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
responseStream << ( !form.empty() ? form.get("passphrase-existing", "") : "" );
responseStream << "</textarea>\n";
responseStream << "\t\t</fieldset>\n";
responseStream << "\t\t\n";
responseStream << "\t\t<input class=\"grd-form-bn grd-form-bn-succeed grd_clickable\" type=\"submit\" name=\"submit\" value=\"Weiter\">\n";
responseStream << "\t\t\n";
responseStream << "\t</form>\n";
responseStream << "\t";
#line 124 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
} else { responseStream << "\n";
responseStream << "\t\t<div class=\"grd_text\">\n";
responseStream << "\t\t\tUngültige Seite, wenn du das siehst stimmt hier etwas nicht. Bitte wende dich an den Server-Admin. \n";
responseStream << "\t\t</div>\n";
responseStream << "\t";
#line 99 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
#line 128 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp"
} responseStream << "\n";
responseStream << "</div>\n";
// begin include footer.cpsp

View File

@ -9,6 +9,12 @@
#include "../SingletonManager/SessionManager.h"
#include "Poco/Net/HTTPCookie.h"
enum PageState {
PAGE_STATE_ASK_PASSWORD,
PAGE_STATE_SUCCEED
};
#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp"
#include "../ServerConfig.h"
@ -28,12 +34,14 @@ void UpdateUserPasswordPage::handleRequest(Poco::Net::HTTPServerRequest& request
if (_compressResponse) response.set("Content-Encoding", "gzip");
Poco::Net::HTMLForm form(request, request.stream());
#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
const char* pageName = "Passwort bestimmen";
auto user = mSession->getUser();
auto sm = SessionManager::getInstance();
auto uri_start = ServerConfig::g_serverPath;
PageState state = PAGE_STATE_ASK_PASSWORD;
// remove old cookies if exist
sm->deleteLoginCookies(request, response, mSession);
// save login cookie, because maybe we've get an new session
@ -45,7 +53,10 @@ void UpdateUserPasswordPage::handleRequest(Poco::Net::HTTPServerRequest& request
if(pwd != form.get("register-password2", "")) {
mSession->addError(new Error("Passwort", "Passw&ouml;rter sind nicht identisch."));
} else if(SessionManager::getInstance()->checkPwdValidation(pwd, mSession)) {
if(user->setNewPassword(form.get("register-password"))) {
auto sessionState = mSession->getSessionState();
if(user->updatePassword(pwd, "")) {
//std::string referUri = request.get("Referer", uri_start + "/");
//printf("[updateUserPasswordPage] redirect to referUri: %s\n", referUri.data());
@ -54,21 +65,30 @@ void UpdateUserPasswordPage::handleRequest(Poco::Net::HTTPServerRequest& request
//! -1 = invalid code
//! -2 = critical error
//! 0 = ok
auto ret = mSession->updateEmailVerification(mSession->getEmailVerificationCode());
auto code = mSession->getEmailVerificationCode();
int retUpdateEmailCode = 0;
if(code) {
retUpdateEmailCode = mSession->updateEmailVerification(mSession->getEmailVerificationCode());
}
mSession->getErrors(user);
if(-2 == ret || -1 == ret || 1 == ret) {
if(-2 == retUpdateEmailCode || -1 == retUpdateEmailCode || 1 == retUpdateEmailCode) {
response.redirect(uri_start + "/error500");
return;
}
response.redirect(uri_start + "/passphrase");
return;
if(sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) {
state = PAGE_STATE_SUCCEED;
mSession->updateState(SESSION_STATE_RESET_PASSWORD_SUCCEED);
} else {
response.redirect(uri_start + "/passphrase");
return;
}
}
}
}
}
getErrors(mSession);
getErrors(user);
printf("session state end [UpdateUserPassword Page]: %s\n", mSession->getSessionStateString());
std::ostream& _responseStream = response.send();
Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1);
std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;
@ -149,9 +169,12 @@ void UpdateUserPasswordPage::handleRequest(Poco::Net::HTTPServerRequest& request
// end include header_old.cpsp
responseStream << "\n";
responseStream << "<div class=\"grd_container\">\n";
responseStream << "\t";
#line 72 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
if(PAGE_STATE_ASK_PASSWORD == state ) { responseStream << "\n";
responseStream << "\t<h1>Passwort bestimmen</h1>\n";
responseStream << "\t";
#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
#line 74 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
responseStream << ( getErrorsHtml() );
responseStream << "\n";
responseStream << "\t<form method=\"POST\">\t\n";
@ -171,6 +194,17 @@ void UpdateUserPasswordPage::handleRequest(Poco::Net::HTTPServerRequest& request
responseStream << "\t\t</fieldset>\n";
responseStream << "\t\t<input class=\"grd-form-bn grd-form-bn-succeed grd_clickable\" type=\"submit\" name=\"submit\" value=\"&Auml;nderung(en) speichern\">\n";
responseStream << "\t</form>\n";
responseStream << "\t";
#line 92 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
} else if(PAGE_STATE_SUCCEED == state) { responseStream << "\n";
responseStream << "\t\t<p>Deine Daten werden jetzt mit dem neuen Passwort verschl&uuml;sselt. Du kannst dich in etwa 1 Minute mit deinem neuen Passwort einloggen</p>\n";
responseStream << "\t\t<a href=\"";
#line 94 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
responseStream << ( uri_start );
responseStream << "/login\" class=\"grd-form-bn grd-form-bn-succeed\">Zum Login</a>\n";
responseStream << "\t";
#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\UpdateUserPassword.cpsp"
} responseStream << "\n";
responseStream << "</div>\n";
// begin include footer.cpsp
responseStream << "\t<div class=\"grd-time-used dev-info\">\n";

View File

@ -0,0 +1,47 @@
#include "JsonGetRunningUserTasks.h"
#include "Poco/URI.h"
#include "../SingletonManager/SingletonTaskObserver.h"
Poco::JSON::Object* JsonGetRunningUserTasks::handle(Poco::Dynamic::Var params)
{
std::string email;
Poco::JSON::Object* result = new Poco::JSON::Object;
if (params.isStruct()) {
auto _email = params["email"];
int zahl = 0;
//std::string miau = params["miau"];
}
else if (params.isVector()) {
const Poco::URI::QueryParameters queryParams = params.extract<Poco::URI::QueryParameters>();
for (auto it = queryParams.begin(); it != queryParams.end(); it++) {
if (it->first == "email") {
email = it->second;
break;
}
}
}
if (email != "") {
auto ob = SingletonTaskObserver::getInstance();
auto tasks = ob->getTasksCount(email);
Poco::JSON::Object tasksJson;
if (tasks.size() > 0) {
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
if (tasks[i] > 0) {
std::string typeName = SingletonTaskObserver::TaskObserverTypeToString(static_cast<TaskObserverType>(i));
tasksJson.set(typeName, tasks[i]);
}
}
}
result->set("state", "success");
result->set("runningTasks", tasksJson);
}
else {
result->set("state", "error");
result->set("msg", "empty email");
}
return result;
}

View File

@ -0,0 +1,16 @@
#ifndef __JSON_INTERFACE_JSON_GET_RUNNING_USER_TASKS_
#define __JSON_INTERFACE_JSON_GET_RUNNING_USER_TASKS_
#include "JsonRequestHandler.h"
class JsonGetRunningUserTasks : public JsonRequestHandler
{
public:
Poco::JSON::Object* handle(Poco::Dynamic::Var params);
protected:
};
#endif // __JSON_INTERFACE_JSON_GET_RUNNING_USER_TASKS_

View File

@ -7,6 +7,7 @@
#include "JsonGetLogin.h"
#include "JsonUnknown.h"
#include "JsonTransaction.h"
#include "JsonGetRunningUserTasks.h"
JsonRequestHandlerFactory::JsonRequestHandlerFactory()
: mRemoveGETParameters("^/([a-zA-Z0-9_-]*)")
@ -25,6 +26,9 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
else if (url_first_part == "/checkTransaction") {
return new JsonTransaction;
}
else if (url_first_part == "/getRunningUserTasks") {
return new JsonGetRunningUserTasks;
}
return new JsonUnknown;
}

View File

@ -0,0 +1,209 @@
#include "SingletonTaskObserver.h"
#include "ErrorManager.h"
SingletonTaskObserver::SingletonTaskObserver()
{
}
SingletonTaskObserver::~SingletonTaskObserver()
{
}
SingletonTaskObserver* SingletonTaskObserver::getInstance()
{
static SingletonTaskObserver one;
return &one;
}
void SingletonTaskObserver::addTask(const std::string& email, TaskObserverType type)
{
DHASH id = makeHash(email);
static const char* funcName = "SingletonTaskObserver::addTask_email";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry) {
entry = new UserObserverEntry(email, id);
}
if (entry->mEmail != email) {
em->addError(new ParamError(funcName, "hash collision with ", email.data()));
em->addError(new ParamError(funcName, "and ", entry->mEmail.data()));
em->sendErrorsAsEmail();
}
entry->mTasksCount[type]++;
unlock();
}
void SingletonTaskObserver::addTask(DHASH id, TaskObserverType type)
{
static const char* funcName = "SingletonTaskObserver::addTask_id";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry) {
entry = new UserObserverEntry("", id);
}
entry->mTasksCount[type]++;
unlock();
}
void SingletonTaskObserver::removeTask(const std::string& email, TaskObserverType type)
{
DHASH id = makeHash(email);
static const char* funcName = "SingletonTaskObserver::removeTask_email";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (entry) {
if (entry->mTasksCount[type] > 0) {
entry->mTasksCount[type]--;
}
else {
em->addError(new ParamError(funcName, "error more calls of removeTasks as addTasks", type));
em->sendErrorsAsEmail();
}
bool oneIsNotZero = false;
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
if (entry->mTasksCount[type] != 0) {
oneIsNotZero = true;
continue;
}
}
if (!oneIsNotZero) {
mObserverEntrys.removeByHash(id);
delete entry;
}
}
else {
em->addError(new Error(funcName, "entry not found"));
em->sendErrorsAsEmail();
}
unlock();
}
void SingletonTaskObserver::removeTask(DHASH id, TaskObserverType type)
{
static const char* funcName = "SingletonTaskObserver::removeTask_id";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (entry) {
if (entry->mTasksCount[type] > 0) {
entry->mTasksCount[type]--;
}
else {
em->addError(new ParamError(funcName, "error more calls of removeTasks as addTasks", type));
em->sendErrorsAsEmail();
}
bool oneIsNotZero = false;
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
if (entry->mTasksCount[type] != 0) {
oneIsNotZero = true;
continue;
}
}
if (!oneIsNotZero) {
mObserverEntrys.removeByHash(id);
delete entry;
}
}
else {
em->addError(new Error(funcName, "entry not found"));
em->sendErrorsAsEmail();
}
unlock();
}
bool SingletonTaskObserver::removeTasksCount(const std::string& email)
{
DHASH id = makeHash(email);
static const char* funcName = "SingletonTaskObserver::removeTasksCount";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (entry) {
mObserverEntrys.removeByHash(id);
unlock();
delete entry;
return true;
}
else {
unlock();
return false;
}
}
int SingletonTaskObserver::getTaskCount(const std::string& email, TaskObserverType type)
{
DHASH id = makeHash(email);
lock("SingletonTaskObserver::getTaskCount");
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry || entry->mEmail != email) {
unlock();
return -1;
}
int count = entry->mTasksCount[type];
unlock();
return count;
}
std::vector<int> SingletonTaskObserver::getTasksCount(const std::string& email)
{
DHASH id = makeHash(email);
lock("SingletonTaskObserver::getTasksCount");
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
std::vector<int> taskCounts;
if (!entry || entry->mEmail != email) {
unlock();
return taskCounts;
}
taskCounts.reserve(TASK_OBSERVER_COUNT);
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
taskCounts.push_back(entry->mTasksCount[i]);
}
unlock();
return taskCounts;
}
const char* SingletonTaskObserver::TaskObserverTypeToString(TaskObserverType type)
{
switch (type) {
case TASK_OBSERVER_PASSWORD_CREATION: return "password creation";
case TASK_OBSERVER_SIGN_TRANSACTION: return "sign transaction";
case TASK_OBSERVER_PREPARE_TRANSACTION: return "prepare transaction";
case TASK_OBSERVER_READY_FOR_SIGN_TRANSACTION: return "ready for sign transaction";
case TASK_OBSERVER_COUNT: return "COUNT";
case TASK_OBSERVER_INVALID: return "INVALID";
default: return "UNKNOWN";
}
}
TaskObserverType SingletonTaskObserver::StringToTaskObserverType(const std::string& typeString)
{
if ("password creation" == typeString) {
return TASK_OBSERVER_PASSWORD_CREATION;
}
else if ("sign transaction" == typeString) {
return TASK_OBSERVER_SIGN_TRANSACTION;
}
else if ("prepare transaction" == typeString) {
return TASK_OBSERVER_PREPARE_TRANSACTION;
}
else if ("ready for sign transaction" == typeString) {
return TASK_OBSERVER_READY_FOR_SIGN_TRANSACTION;
}
return TASK_OBSERVER_INVALID;
}

View File

@ -0,0 +1,74 @@
/*!
*
* \author: einhornimmond
*
* \date: 10.01.20
*
* \brief: observe tasks, for example passwort creation or transactions
*/
#ifndef DR_GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_SINGLETON_TASK_OBSERVER_H
#define DR_GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_SINGLETON_TASK_OBSERVER_H
#include "Poco/Mutex.h"
#include "../lib/DRHashList.h"
#include "../lib/MultithreadContainer.h"
#include <vector>
enum TaskObserverType {
TASK_OBSERVER_PASSWORD_CREATION,
TASK_OBSERVER_SIGN_TRANSACTION,
TASK_OBSERVER_PREPARE_TRANSACTION,
TASK_OBSERVER_READY_FOR_SIGN_TRANSACTION,
TASK_OBSERVER_COUNT,
TASK_OBSERVER_INVALID
};
class SingletonTaskObserver : public UniLib::lib::MultithreadContainer
{
public:
~SingletonTaskObserver();
static SingletonTaskObserver* getInstance();
void addTask(DHASH id, TaskObserverType type);
void addTask(const std::string& email, TaskObserverType type);
void removeTask(DHASH id, TaskObserverType type);
void removeTask(const std::string& email, TaskObserverType type);
//! \return true if found and deleted
//! \return false if not found
bool removeTasksCount(const std::string& email);
//! \return -1 if no entry for email found
int getTaskCount(const std::string& email, TaskObserverType type);
std::vector<int> getTasksCount(const std::string& email);
static const char* TaskObserverTypeToString(TaskObserverType type);
static TaskObserverType StringToTaskObserverType(const std::string& typeString);
protected:
SingletonTaskObserver();
inline DHASH makeHash(const std::string& email) { return DRMakeStringHash(email.data(), email.size()); }
struct UserObserverEntry
{
UserObserverEntry(const std::string& email, DHASH id)
: mEmail(email), mHash(id) {
memset(mTasksCount, 0, TASK_OBSERVER_COUNT * sizeof(int));
}
std::string mEmail;
DHASH mHash;
int mTasksCount[TASK_OBSERVER_COUNT];
};
DRHashList mObserverEntrys;
};
#endif //DR_GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_SINGLETON_TASK_OBSERVER_H

View File

@ -19,6 +19,8 @@ namespace controller {
static std::vector<Poco::AutoPtr<EmailVerificationCode>> load(int user_id);
static Poco::AutoPtr<EmailVerificationCode> load(int user_id, model::table::EmailOptInType type);
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
inline Poco::AutoPtr<model::table::EmailOptIn> getModel() { return _getModel<model::table::EmailOptIn>(); }
std::string getLink();

View File

@ -22,17 +22,10 @@ int main(int argc, char** argv)
printf("error initing sodium, early exit\n");
return -1;
}
ServerConfig::g_versionString = "0.10.1";
ServerConfig::g_versionString = "0.11.0";
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");
Profiler timeUsed;
testUser->validatePwd("haz27Newpassword", nullptr);
ServerConfig::g_FakeLoginSleepTime = (int)std::round(timeUsed.millis());
delete testUser;
Gradido_LoginServer app;
return app.run(argc, argv);

View File

@ -34,7 +34,7 @@ int WriteEmailVerification::run()
mEmailVerificationCode->getModel()->setUserId(mUser->getDBId());
auto emailVerificationModel = mEmailVerificationCode->getModel();
emailVerificationModel->setUserId(mUser->getDBId());
if (!emailVerificationModel->insertIntoDB() || emailVerificationModel->errorCount() > 0) {
if (!emailVerificationModel->insertIntoDB(true) || emailVerificationModel->errorCount() > 0) {
emailVerificationModel->sendErrorsAsEmail();
return -1;
}
@ -91,6 +91,8 @@ Session::~Session()
unlock();
reset();
}
//printf("[Session::~Session] finished \n");
}
@ -280,64 +282,76 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
Profiler usedTime;
auto em = ErrorManager::getInstance();
if(getEmailVerificationCode() == emailVerificationCode) {
if (mEmailVerificationCodeObject.isNull()) {
em->addError(new Error(funcName, "email verification object is zero"));
em->sendErrorsAsEmail();
unlock();
return -2;
}
auto emailVerificationCodeModel = mEmailVerificationCodeObject->getModel();
if(emailVerificationCodeModel->getCode() == 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"));
em->sendErrorsAsEmail();
unlock();
//return false;
return -2;
}
// load correct user from db
auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select(dbConnection);
bool emailChecked = false;
int userId = 0;
select << "SELECT email_checked, id from users where id = (SELECT user_id FROM email_opt_in where verification_code=?)",
into(emailChecked), into(userId), use(emailVerificationCode);
if (mNewUser.isNull() || mNewUser->getModel()->getID() != emailVerificationCodeModel->getUserId()) {
mNewUser = controller::User::create();
if (1 != mNewUser->load(emailVerificationCodeModel->getUserId())) {
em->addError(new ParamError(funcName, "user load didn't return 1 with user_id ", emailVerificationCodeModel->getUserId()));
em->sendErrorsAsEmail();
unlock();
return -2;
}
}
try {
select.execute();
auto userModel = mNewUser->getModel();
bool firstEmailActivation = false;
if (emailVerificationCodeModel->getType() == model::table::EMAIL_OPT_IN_REGISTER || emailVerificationCodeModel->getType() == model::table::EMAIL_OPT_IN_EMPTY) {
firstEmailActivation = true;
}
catch (Poco::Exception& ex) {
em->addError(new ParamError(funcName, "select user from email verification code mysql error ", ex.displayText().data()));
em->sendErrorsAsEmail();
}
if (userId != 0 && emailChecked) {
mSessionUser = new User(userId);
if (firstEmailActivation && userModel->isEmailChecked()) {
mSessionUser = new User(mNewUser);
addError(new Error(gettext("E-Mail Verification"), gettext("Du hast dein Konto bereits aktiviert!")));
unlock();
return 1;
}
if (userId == 0) {
addError(new Error(gettext("E-Mail Verification"), gettext("Der Code stimmt nicht, bitte &uuml;berpr&uuml;fe ihn nochmal oder registriere dich erneut oder wende dich an den Server-Admin")));
//printf("[%s] time: %s\n", funcName, usedTime.string().data());
if (firstEmailActivation) {
userModel->setEmailChecked(true);
userModel->updateIntoDB("email_checked", 1);
if (userModel->errorCount() > 0) {
userModel->sendErrorsAsEmail();
}
unlock();
return -1;
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
return 0;
}
Poco::Data::Statement update(dbConnection);
update << "UPDATE users SET email_checked=1 where id = ?", use(userId);
try {
auto updated_rows = update.execute();
if (!updated_rows) {
//addError(new Error(gettext("E-Mail Verification"), gettext("Der Code stimmt nicht, bitte &uuml;berpr&uuml;fe ihn nochmal oder registriere dich erneut oder wende dich an den Server-Admin")));
//printf("[%s] time: %s\n", funcName, usedTime.string().data());
em->addError(new Error(funcName, "impossible error, update users failed with shortly before acquired user id "));
if (emailVerificationCodeModel->getType() == model::table::EMAIL_OPT_IN_RESET_PASSWORD) {
unlock();
if (mEmailVerificationCodeObject->deleteFromDB()) {
mEmailVerificationCodeObject = nullptr;
}
else {
em->getErrors(mEmailVerificationCodeObject->getModel());
em->addError(new Error(funcName, "error deleting email verification code"));
em->sendErrorsAsEmail();
unlock();
return -2;
}
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
}
catch (Poco::Exception& ex) {
em->addError(new ParamError(funcName, "update user from email verification code mysql error ", ex.displayText().data()));
em->sendErrorsAsEmail();
unlock();
return -2;
updateState(SESSION_STATE_RESET_PASSWORD_REQUEST);
return 0;
}
em->addError(new Error(funcName, "invalid code path"));
em->sendErrorsAsEmail();
unlock();
return -2;
/*if (updated_rows == 1) {
Poco::Data::Statement delete_row(dbConnection);
delete_row << "DELETE FROM email_opt_in where verification_code = ?", use(emailVerificationCode);
@ -376,6 +390,7 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
int Session::resetPassword(Poco::AutoPtr<controller::User> user, bool passphraseMemorized)
{
mNewUser = user;
mSessionUser = new User(user);
if (passphraseMemorized) {
// first check if already exist
@ -387,7 +402,7 @@ int Session::resetPassword(Poco::AutoPtr<controller::User> user, bool passphrase
auto emailVerificationModel = mEmailVerificationCodeObject->getModel();
UniLib::controller::TaskPtr insertEmailVerificationCode(
new model::table::ModelInsertTask(emailVerificationModel, true)
new model::table::ModelInsertTask(emailVerificationModel, true, true)
);
insertEmailVerificationCode->scheduleTask(insertEmailVerificationCode);
UniLib::controller::TaskPtr sendEmail(new SendEmailTask(
@ -404,6 +419,37 @@ int Session::resetPassword(Poco::AutoPtr<controller::User> user, bool passphrase
return 0;
}
int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, Mnemonic* wordSource)
{
KeyPair keys;
static const char* functionName = "Session::comparePassphraseWithSavedKeys";
if (!wordSource) {
addError(new Error(functionName, "wordSource is empty"));
sendErrorsAsEmail();
return -2;
}
if (!keys.generateFromPassphrase(inputPassphrase.data(), wordSource)) {
addError(new Error(gettext("Passphrase"), gettext("Deine Passphrase ist ung&uuml;tig")));
return 0;
}
auto userModel = mNewUser->getModel();
auto existingPublic = userModel->getPublicKey();
if (!existingPublic) {
userModel->loadFromDB("email", userModel->getEmail());
existingPublic = userModel->getPublicKey();
if (!existingPublic) {
addError(new Error(gettext("Passphrase"), gettext("Ein Fehler trat auf, bitte versuche es erneut")));
return -1;
}
}
if (0 == memcmp(userModel->getPublicKey(), keys.getPublicKey(), crypto_sign_PUBLICKEYBYTES)) {
mPassphrase = inputPassphrase;
return 1;
}
addError(new Error(gettext("Passphrase"), gettext("Das ist nicht die richtige Passphrase.")));
return 0;
}
bool Session::startProcessingTransaction(const std::string& proto_message_base64)
{
lock("Session::startProcessingTransaction");
@ -419,6 +465,7 @@ bool Session::startProcessingTransaction(const std::string& proto_message_base64
return false;
}
}
Poco::AutoPtr<ProcessingTransaction> processorTask(new ProcessingTransaction(proto_message_base64));
processorTask->scheduleTask(processorTask);
mProcessingTransactions.push_back(processorTask);
@ -686,7 +733,8 @@ void Session::detectSessionState()
updateState(SESSION_STATE_KEY_PAIR_WRITTEN);
if (resetPasswd != -1) {
updateState(SESSION_STATE_RESET_PASSWORD_REQUEST);
// don't go to reset password screen after login, only throw checkEmail
//updateState(SESSION_STATE_RESET_PASSWORD_REQUEST);
return;
}
@ -778,6 +826,8 @@ const char* Session::translateSessionStateToString(SessionStates state)
case SESSION_STATE_PASSPHRASE_WRITTEN: return "Passphrase written";
case SESSION_STATE_KEY_PAIR_GENERATED: return "Gradido Address created";
case SESSION_STATE_KEY_PAIR_WRITTEN: return "Gradido Address saved";
case SESSION_STATE_RESET_PASSWORD_REQUEST: return "Passwort reset requested";
case SESSION_STATE_RESET_PASSWORD_SUCCEED: return "Passwort reset succeeded";
default: return "unknown";
}

View File

@ -45,6 +45,7 @@ enum SessionStates {
SESSION_STATE_KEY_PAIR_GENERATED,
SESSION_STATE_KEY_PAIR_WRITTEN,
SESSION_STATE_RESET_PASSWORD_REQUEST,
SESSION_STATE_RESET_PASSWORD_SUCCEED,
SESSION_STATE_COUNT
};
@ -95,6 +96,12 @@ public:
//! \return 1 = reset password email already send
//! \return 0 = ok
int resetPassword(Poco::AutoPtr<controller::User> 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();
@ -126,6 +133,8 @@ public:
inline Poco::DateTime getLastActivity() { return mLastActivity; }
// ------------------------ transactions functions ----------------------------
//! \return true if succeed
bool startProcessingTransaction(const std::string& proto_message_base64);
//! \param working if set will filled with transaction running

View File

@ -10,6 +10,7 @@
#include "../SingletonManager/ErrorManager.h"
#include "../SingletonManager/SessionManager.h"
#include "../SingletonManager/LanguageManager.h"
#include "../SingletonManager/SingletonTaskObserver.h"
#include "Poco/Data/Binding.h"
@ -21,6 +22,14 @@ using namespace Poco::Data::Keywords;
// -------------------------------------------------------------------------------------------------
UserCreateCryptoKey::UserCreateCryptoKey(Poco::AutoPtr<User> user, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler)
: UniLib::controller::CPUTask(cpuScheduler), mUser(user), mPassword(password) {
#ifdef _UNI_LIB_DEBUG
setName(user->getEmail());
#endif
}
int UserCreateCryptoKey::run()
{
auto cryptoKey = mUser->createCryptoKey(mPassword);
@ -30,11 +39,11 @@ int UserCreateCryptoKey::run()
printf("[UserCreateCryptoKey] crypto_shorthash_BYTES != sizeof(mPasswordHashed)\n");
throw Poco::Exception("crypto_shorthash_BYTES != sizeof(mPasswordHashed)");
}
User::passwordHashed pwdHashed;
crypto_shorthash((unsigned char*)&pwdHashed, *cryptoKey, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey);
auto pwdHashed = mUser->createPasswordHashed(cryptoKey);
mUser->setPwdHashed(pwdHashed);
//printf("crypto key created\n");
setTaskFinished();
// must poke cpu scheduler manually because another task is waiting for this task, but in the other scheduler
@ -504,7 +513,7 @@ std::string User::generateNewPassphrase(Mnemonic* word_source)
return phrase_buffer;
}
bool User::validatePassphrase(const std::string& passphrase)
bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/)
{
std::istringstream iss(passphrase);
std::vector<std::string> results(std::istream_iterator<std::string>{iss},
@ -518,7 +527,12 @@ bool User::validatePassphrase(const std::string& passphrase)
continue;
}
}
if (existAll) return true;
if (existAll) {
if (wordSource) {
*wordSource = &m;
}
return true;
}
}
return false;
}
@ -559,6 +573,7 @@ Poco::JSON::Object User::getJson()
return userObj;
}
/*
// TODO: if a password and privkey already exist, load current private key and re encrypt with new crypto key
bool User::setNewPassword(const std::string& newPassword)
{
@ -571,7 +586,7 @@ bool User::setNewPassword(const std::string& newPassword)
}
if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) {
lock("User::setNewPassword");
addError(new Error("Passwort", "Wird bereits erstellt, bitte in ca. 1 sekunde neuladen."));
addError(new Error("Passwort", "Wird bereits erstellt, bitte in ca. 1 minute neuladen."));
unlock();
return false;
}
@ -589,6 +604,94 @@ bool User::setNewPassword(const std::string& newPassword)
savePassword->scheduleTask(savePassword);
//printf("[User::setNewPassword] timeUsed: %s\n", timeUsed.string().data());
return true;
}
*/
bool User::updatePassword(const std::string& newPassword, const std::string& passphrase)
{
static const char* functionName("User::updatePassword");
if (newPassword == "") {
lock(functionName);
addError(new Error(gettext("Passwort"), gettext("Ist leer.")));
unlock();
return false;
}
if (!mCreateCryptoKeyTask.isNull() && !mCreateCryptoKeyTask->isTaskFinished()) {
lock(functionName);
addError(new Error(gettext("Passwort"), gettext("Wird bereits erstellt, bitte in ca. 1 minute neuladen.")));
unlock();
return false;
}
//duplicate();
//lock("User::setNewPassword");
//printf("[User::setNewPassword] start create crypto key task with this: %d\n", this);
//mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newPassword, ServerConfig::g_CPUScheduler);
//mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask);
//unlock();
auto mm = MemoryManager::getInstance();
bool passwordHashedCalculated = false;
// no previous password set
if (!mPasswordHashed) {
duplicate();
lock(functionName);
//printf("[User::setNewPassword] start create crypto key task with this: %d\n", this);
mCreateCryptoKeyTask = new UserCreateCryptoKey(this, newPassword, ServerConfig::g_CPUScheduler);
mCreateCryptoKeyTask->scheduleTask(mCreateCryptoKeyTask);
unlock();
}
else {
// compare with previous password
auto cryptoKey = createCryptoKey(newPassword);
auto passwordHash = createPasswordHashed(cryptoKey);
lock(functionName);
if (mPasswordHashed == passwordHash) {
addError(new Error(gettext("Passwort"), gettext("Du hast dasselbe Passwort gew&auml;hlt, bitte w&auml;hle ein anderes.")));
unlock();
mm->releaseMemory(cryptoKey);
return false;
}
mPasswordHashed = passwordHash;
passwordHashedCalculated = true;
if (mCryptoKey) {
mm->releaseMemory(mCryptoKey);
}
mCryptoKey = cryptoKey;
unlock();
}
duplicate();
UniLib::controller::TaskPtr savePassword(nullptr);
UserWriteCryptoKeyHashIntoDB* writePWDHashedIntoDB = nullptr;
if (passwordHashedCalculated) {
savePassword = new UserWriteCryptoKeyHashIntoDB(this, 0);
}
else {
savePassword = new UserWriteCryptoKeyHashIntoDB(this, 1);
savePassword->setParentTaskPtrInArray(mCreateCryptoKeyTask, 0);
}
savePassword->scheduleTask(savePassword);
if (passphrase != "") {
duplicate();
UniLib::controller::TaskPtr genKeys(new UserGenerateKeys(this, passphrase));
genKeys->scheduleTask(genKeys);
std::vector<UniLib::controller::TaskPtr> saveKeysParents;
saveKeysParents.reserve(2); // to prevent allocating more memory as ever needed
saveKeysParents.push_back(genKeys);
if (!passwordHashedCalculated) {
saveKeysParents.push_back(mCreateCryptoKeyTask);
}
duplicate();
UniLib::controller::TaskPtr saveKeys(new UserWriteKeysIntoDB(saveKeysParents, this, true));
saveKeys->scheduleTask(saveKeys);
}
//printf("[User::setNewPassword] timeUsed: %s\n", timeUsed.string().data());
return true;
}
@ -711,9 +814,7 @@ void User::duplicate()
void User::release()
{
if (!mCreateCryptoKeyTask.isNull() && mCreateCryptoKeyTask->isTaskFinished()) {
mCreateCryptoKeyTask = nullptr;
}
Poco::Mutex::ScopedLock _lock(mReferenceMutex);
//mReferenceMutex.lock();
mReferenceCount--;
@ -734,18 +835,30 @@ MemoryBin* User::createCryptoKey(const std::string& password)
//Profiler timeUsed;
auto mm = MemoryManager::getInstance();
auto observer = SingletonTaskObserver::getInstance();
static const char* funcName = "User::createCryptoKey";
if (mEmail == "") {
lock(funcName);
addError(new Error(funcName, "email is empty"));
unlock();
return nullptr;
}
// TODO: put it in secure location, or use value from server config
static const unsigned char app_secret[] = { 0x21, 0xff, 0xbb, 0xc6, 0x16, 0xfe };
sha_context context_sha512;
//unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE);
if (SHA_512_SIZE < crypto_pwhash_SALTBYTES) {
lock("User::createCryptoKey");
addError(new Error(__FUNCTION__, "sha512 is to small for libsodium pwhash saltbytes"));
lock(funcName);
addError(new Error(funcName, "sha512 is to small for libsodium pwhash saltbytes"));
unlock();
return nullptr;
}
observer->addTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION);
unsigned char hash512_salt[SHA_512_SIZE]; // need at least crypto_pwhash_SALTBYTES 16U
sha512_init(&context_sha512);
@ -760,13 +873,15 @@ MemoryBin* User::createCryptoKey(const std::string& password)
//Bin32Bytes* key = mm->get32Bytes();
if (crypto_pwhash(*key, key->size(), password.data(), password.size(), hash512_salt, 10U, 33554432, 2) != 0) {
lock("User::createCryptoKey");
addError(new ParamError(__FUNCTION__, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno)));
lock(funcName);
addError(new ParamError(funcName, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno)));
unlock();
observer->removeTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION);
//printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno));
//printf("pwd: %s\n", pwd);
return nullptr;
}
observer->removeTask(mEmail, TASK_OBSERVER_PASSWORD_CREATION);
// lock();
// auto cryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key);
@ -778,6 +893,23 @@ MemoryBin* User::createCryptoKey(const std::string& password)
return key;
}
User::passwordHashed User::createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver/* = nullptr*/)
{
if (sizeof(User::passwordHashed) != crypto_shorthash_BYTES) {
throw Poco::Exception("crypto_shorthash_BYTES != sizeof(User::passwordHashed)");
}
User::passwordHashed pwdHashed = 0;
if (!ServerConfig::g_ServerCryptoKey) {
if (errorReceiver) {
errorReceiver->addError(new Error("User::validatePwd", "server crypto key not set"));
}
return pwdHashed;
}
crypto_shorthash((unsigned char*)&pwdHashed, *cryptoKey, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey);
return pwdHashed;
}
void User::fakeCreateCryptoKey()
{
Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime);

View File

@ -73,7 +73,7 @@ public:
~User();
static std::string generateNewPassphrase(Mnemonic* word_source);
static bool validatePassphrase(const std::string& passphrase);
static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr);
static const char* userStateToString(UserStates state);
//static User* login(const std::string& email, const std::string& password, ErrorList* errorContainer = nullptr);
@ -105,7 +105,8 @@ public:
inline void setBalance(int balance) { lock(); mGradidoCurrentBalance = balance; unlock(); }
void setEmailChecked();
bool isEmptyPassword();
bool setNewPassword(const std::string& newPassword);
//bool setNewPassword(const std::string& newPassword);
bool updatePassword(const std::string& newPassword, const std::string& passphrase);
bool validatePwd(const std::string& pwd, ErrorList* validationErrorsToPrint);
bool validateIdentHash(HASH hash);
@ -125,6 +126,7 @@ protected:
typedef Poco::UInt64 passwordHashed;
MemoryBin* createCryptoKey(const std::string& password);
static passwordHashed createPasswordHashed(MemoryBin* cryptoKey, ErrorList* errorReceiver = nullptr);
inline void setCryptoKey(MemoryBin* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); }
//void detectState();
@ -182,12 +184,7 @@ private:
class UserCreateCryptoKey : public UniLib::controller::CPUTask
{
public:
UserCreateCryptoKey(Poco::AutoPtr<User> user, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler)
: UniLib::controller::CPUTask(cpuScheduler), mUser(user), mPassword(password) {
#ifdef _UNI_LIB_DEBUG
setName(user->getEmail());
#endif
}
UserCreateCryptoKey(Poco::AutoPtr<User> user, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler);
virtual int run();
virtual const char* getResourceType() const { return "UserCreateCryptoKey"; };

View File

@ -91,6 +91,18 @@ namespace model {
throw Poco::Exception("ElopageBuy::loadFromDB not implemented");
}
Poco::Data::Statement ElopageBuy::_loadIdFromDB(Poco::Data::Session session)
{
Poco::Data::Statement select(session);
select << "SELECT id FROM " << getTableName()
<< " where order_id = ?"
, into(mID), use(mIDs[ELOPAGE_BUY_ORDER_ID]);
return select;
}
}
}

View File

@ -39,6 +39,7 @@ namespace model {
std::string toString();
protected:
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);

View File

@ -53,15 +53,25 @@ namespace model {
{
Poco::Data::Statement select(session);
select << "SELECT user_id, verification_code, email_opt_in_type_id FROM " << getTableName()
select << "SELECT id, user_id, verification_code, email_opt_in_type_id FROM " << getTableName()
<< " where " << fieldName << " = ?"
, into(mUserId), into(mEmailVerificationCode), into(mType);
, into(mID), into(mUserId), into(mEmailVerificationCode), into(mType);
return select;
}
Poco::Data::Statement EmailOptIn::_loadIdFromDB(Poco::Data::Session session)
{
Poco::Data::Statement select(session);
select << "SELECT id FROM " << getTableName()
<< " where verification_code = ?"
, into(mID), use(mEmailVerificationCode);
return select;
}
Poco::Data::Statement EmailOptIn::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName)
{
Poco::Data::Statement select(session);

View File

@ -40,6 +40,7 @@ namespace model {
static const char* typeToString(EmailOptInType type);
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
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);

View File

@ -10,8 +10,8 @@
namespace model {
namespace table {
ModelInsertTask::ModelInsertTask(Poco::AutoPtr<ModelBase> model, bool emailErrors /* = false */)
: UniLib::controller::CPUTask(ServerConfig::g_CPUScheduler), mModel(model), mEmailErrors(emailErrors)
ModelInsertTask::ModelInsertTask(Poco::AutoPtr<ModelBase> model, bool loadId, bool emailErrors /* = false */)
: UniLib::controller::CPUTask(ServerConfig::g_CPUScheduler), mModel(model), mEmailErrors(emailErrors), mLoadId(loadId)
{
#ifdef _UNI_LIB_DEBUG
setName(model->getTableName());
@ -21,7 +21,7 @@ namespace model {
int ModelInsertTask::run()
{
auto result = mModel->insertIntoDB();
auto result = mModel->insertIntoDB(mLoadId);
if (mModel->errorCount() > 0 && mEmailErrors) {
mModel->sendErrorsAsEmail();
}
@ -38,19 +38,35 @@ namespace model {
unlock();
}
bool ModelBase::insertIntoDB()
bool ModelBase::insertIntoDB(bool loadId)
{
printf("ModelBase::insertIntoDB with table: %s\n", getTableName());
//printf("ModelBase::insertIntoDB with table: %s\n", getTableName());
auto cm = ConnectionManager::getInstance();
Poco::Data::Statement insert = _insertIntoDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
size_t resultCount = 0;
try {
return insert.execute() == 1;
if (insert.execute() == 1) {
// load id from db
if (loadId) {
Poco::Data::Statement select = _loadIdFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
try {
return select.execute() == 1;
}
catch (Poco::Exception& ex) {
lock("ModelBase::insertIntoDB");
addError(new ParamError(getTableName(), "mysql error by select id", ex.displayText().data()));
addError(new ParamError(getTableName(), "data set: ", toString().data()));
unlock();
}
}
else {
return true;
}
}
}
catch (Poco::Exception& ex) {
lock();
lock("ModelBase::insertIntoDB2");
addError(new ParamError(getTableName(), "mysql error by insert", ex.displayText().data()));
addError(new ParamError(getTableName(), "data set: ", toString().data()));
unlock();
@ -59,6 +75,30 @@ namespace model {
return false;
}
bool ModelBase::deleteFromDB()
{
if (mID == 0) {
lock();
addError(new Error(getTableName(), "id is zero, couldn't delete from db"));
unlock();
return false;
}
auto cm = ConnectionManager::getInstance();
Poco::Data::Statement deleteStmt(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
deleteStmt << "delete from " << getTableName() << " where id = ?", Poco::Data::Keywords::use(mID);
try {
return deleteStmt.execute() == 1;
}
catch (Poco::Exception& ex) {
lock();
addError(new ParamError(getTableName(), "mysql error by delete", ex.displayText().data()));
addError(new ParamError(getTableName(), "id: ", mID));
unlock();
}
return false;
}
void ModelBase::duplicate()
{
lock();

View File

@ -37,7 +37,9 @@ namespace model {
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();
bool insertIntoDB(bool loadId);
bool deleteFromDB();
inline void setID(int id) { lock(); mID = id; unlock(); }
inline int getID() { lock(); int id = mID; unlock(); return id; }
@ -48,7 +50,7 @@ namespace model {
void duplicate();
void release();
protected:
virtual Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session) = 0;
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);
@ -147,7 +149,7 @@ namespace model {
size_t resultCount = 0;
try {
resultCount = select.execute();
resultCount = update.execute();
}
catch (Poco::Exception& ex) {
lock();
@ -164,7 +166,7 @@ namespace model {
class ModelInsertTask : public UniLib::controller::CPUTask
{
public:
ModelInsertTask(Poco::AutoPtr<ModelBase> model, bool emailErrors = false);
ModelInsertTask(Poco::AutoPtr<ModelBase> model, bool loadId, bool emailErrors = false);
int run();
const char* getResourceType() const { return "ModelInsertTask"; };
@ -172,6 +174,7 @@ namespace model {
protected:
Poco::AutoPtr<ModelBase> mModel;
bool mEmailErrors;
bool mLoadId;
};

View File

@ -77,6 +77,17 @@ namespace model {
return select;
}
Poco::Data::Statement User::_loadIdFromDB(Poco::Data::Session session)
{
Poco::Data::Statement select(session);
select << "SELECT id FROM " << getTableName()
<< " where email = ?"
, into(mID), use(mEmail);
return select;
}
/*
std::string mEmail;
std::string mFirstName;

View File

@ -61,6 +61,7 @@ namespace model {
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
// insert only with email, first_name, last_name, password if exist and language
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);

View File

@ -4,12 +4,19 @@
#include "../model/TransactionCreation.h"
#include "../model/TransactionTransfer.h"
ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64)
: mType(TRANSACTION_NONE), mProtoMessageBase64(proto_message_base64), mTransactionSpecific(nullptr)
#include "../SingletonManager/SingletonTaskObserver.h"
ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash)
: mType(TRANSACTION_NONE), mProtoMessageBase64(proto_message_base64), mTransactionSpecific(nullptr), mUserEmailHash(userEmailHash)
{
mHashMutex.lock();
mHash = calculateHash(proto_message_base64);
mHashMutex.unlock();
auto observer = SingletonTaskObserver::getInstance();
if (userEmailHash != 0) {
observer->addTask(userEmailHash, TASK_OBSERVER_PREPARE_TRANSACTION);
}
}
ProcessingTransaction::~ProcessingTransaction()
@ -19,6 +26,10 @@ ProcessingTransaction::~ProcessingTransaction()
delete mTransactionSpecific;
mTransactionSpecific = nullptr;
}
auto observer = SingletonTaskObserver::getInstance();
if (mUserEmailHash != 0) {
observer->addTask(mUserEmailHash, TASK_OBSERVER_PREPARE_TRANSACTION);
}
unlock();
}

View File

@ -30,7 +30,7 @@ class ProcessingTransaction : public UniLib::controller::CPUTask, public ErrorLi
{
friend SigningTransaction;
public:
ProcessingTransaction(const std::string& proto_message_base64);
ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash);
virtual ~ProcessingTransaction();
int run();
@ -60,6 +60,7 @@ protected:
TransactionBase* mTransactionSpecific;
HASH mHash;
DHASH mUserEmailHash;
Poco::Mutex mHashMutex;
private:

View File

@ -2,6 +2,7 @@
#include "../SingletonManager/ErrorManager.h"
#include "../SingletonManager/MemoryManager.h"
#include "../SingletonManager/SingletonTaskObserver.h"
#include "../lib/Profiler.h"
@ -20,12 +21,18 @@
SigningTransaction::SigningTransaction(Poco::AutoPtr<ProcessingTransaction> processingeTransaction, Poco::AutoPtr<User> user)
: mProcessingeTransaction(processingeTransaction), mUser(user)
{
auto ob = SingletonTaskObserver::getInstance();
if (!mUser.isNull() && mUser->getEmail() != "") {
ob->addTask(mUser->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION);
}
}
SigningTransaction::~SigningTransaction()
{
auto ob = SingletonTaskObserver::getInstance();
if (!mUser.isNull() && mUser->getEmail() != "") {
ob->removeTask(mUser->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION);
}
}
int SigningTransaction::run() {

View File

@ -6,12 +6,14 @@
<%@ page compressed="true" %>
<%!
#include "../SingletonManager/SessionManager.h"
#include "../crypto/KeyPair.h"
//#include "Poco/Net/HTTPServerParams.h"
enum PageState
{
PAGE_ASK_PASSPHRASE,
PAGE_SHOW_PASSPHRASE
PAGE_SHOW_PASSPHRASE,
PAGE_FORCE_ASK_PASSPHRASE
};
%>
<%%
@ -25,17 +27,33 @@ enum PageState
// save login cookie, because maybe we've get an new session
response.addCookie(mSession->getLoginCookie());
if(mSession->getSessionState() == SESSION_STATE_RESET_PASSWORD_REQUEST) {
state = PAGE_FORCE_ASK_PASSPHRASE;
}
if (!form.empty()) {
auto registerKeyChoice = form.get("passphrase", "");
auto registerKeyChoice = form.get("passphrase", "no");
std::string oldPassphrase = "";
if (registerKeyChoice == "no") {
auto oldPassphrase = form.get("passphrase-existing", "");
if (oldPassphrase != "" && User::validatePassphrase(oldPassphrase)) {
auto oldPassphrase = KeyPair::filterPassphrase(form.get("passphrase-existing", ""));
Mnemonic* wordSource = nullptr;
if (oldPassphrase != "" && User::validatePassphrase(oldPassphrase, &wordSource)) {
// passphrase is valid
mSession->setPassphrase(oldPassphrase);
mSession->updateState(SESSION_STATE_PASSPHRASE_SHOWN);
state = PAGE_SHOW_PASSPHRASE;
if(PAGE_FORCE_ASK_PASSPHRASE == state) {
auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, wordSource);
if(-2 == compareResult) {
response.redirect(ServerConfig::g_serverPath + "/error500");
return;
} else if(1 == compareResult) {
response.redirect(ServerConfig::g_serverPath + "/updateUserPassword");
return;
}
} else {
mSession->setPassphrase(oldPassphrase);
mSession->updateState(SESSION_STATE_PASSPHRASE_SHOWN);
state = PAGE_SHOW_PASSPHRASE;
}
}
else {
addError(new Error("Passphrase", "Diese Passphrase ist ung&uuml;ltig, bitte &uuml;berpr&uuml;fen oder neu generieren (lassen)."));
@ -91,6 +109,17 @@ enum PageState
<input class="grd-form-bn grd-form-bn-succeed grd_clickable" type="submit" name="submit" value="Weiter">
</form>
<% } else if(PAGE_FORCE_ASK_PASSPHRASE == state ) { %>
<form method="POST" action="<%= uri_start %>/passphrase">
<fieldset class="grd_container_small">
<legend>Konto wiederherstellen / Neues Passwort anlegen</legend>
<p>Um dein Konto wiederherzustellen, dir ein Neues Passwort ausw&auml;hlen zu können, tippe hier bitte die W&ouml;rter deiner Passphrase in der richtigen Reihenfolge ein, welche du dir aufgeschrieben hast</p>
<textarea style="width:100%;height:100px" name="passphrase-existing"><%= !form.empty() ? form.get("passphrase-existing", "") : "" %></textarea>
</fieldset>
<input class="grd-form-bn grd-form-bn-succeed grd_clickable" type="submit" name="submit" value="Weiter">
</form>
<% } else { %>
<div class="grd_text">

View File

@ -6,12 +6,20 @@
<%!
#include "../SingletonManager/SessionManager.h"
#include "Poco/Net/HTTPCookie.h"
enum PageState {
PAGE_STATE_ASK_PASSWORD,
PAGE_STATE_SUCCEED
};
%>
<%%
const char* pageName = "Passwort bestimmen";
auto user = mSession->getUser();
auto sm = SessionManager::getInstance();
auto uri_start = ServerConfig::g_serverPath;
PageState state = PAGE_STATE_ASK_PASSWORD;
// remove old cookies if exist
sm->deleteLoginCookies(request, response, mSession);
// save login cookie, because maybe we've get an new session
@ -23,7 +31,10 @@
if(pwd != form.get("register-password2", "")) {
mSession->addError(new Error("Passwort", "Passw&ouml;rter sind nicht identisch."));
} else if(SessionManager::getInstance()->checkPwdValidation(pwd, mSession)) {
if(user->setNewPassword(form.get("register-password"))) {
auto sessionState = mSession->getSessionState();
if(user->updatePassword(pwd, "")) {
//std::string referUri = request.get("Referer", uri_start + "/");
//printf("[updateUserPasswordPage] redirect to referUri: %s\n", referUri.data());
@ -32,23 +43,33 @@
//! -1 = invalid code
//! -2 = critical error
//! 0 = ok
auto ret = mSession->updateEmailVerification(mSession->getEmailVerificationCode());
auto code = mSession->getEmailVerificationCode();
int retUpdateEmailCode = 0;
if(code) {
retUpdateEmailCode = mSession->updateEmailVerification(mSession->getEmailVerificationCode());
}
mSession->getErrors(user);
if(-2 == ret || -1 == ret || 1 == ret) {
if(-2 == retUpdateEmailCode || -1 == retUpdateEmailCode || 1 == retUpdateEmailCode) {
response.redirect(uri_start + "/error500");
return;
}
response.redirect(uri_start + "/passphrase");
return;
if(sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) {
state = PAGE_STATE_SUCCEED;
mSession->updateState(SESSION_STATE_RESET_PASSWORD_SUCCEED);
} else {
response.redirect(uri_start + "/passphrase");
return;
}
}
}
}
}
getErrors(mSession);
getErrors(user);
printf("session state end [UpdateUserPassword Page]: %s\n", mSession->getSessionStateString());
%><%@ include file="header_old.cpsp" %>
<div class="grd_container">
<% if(PAGE_STATE_ASK_PASSWORD == state ) { %>
<h1>Passwort bestimmen</h1>
<%= getErrorsHtml() %>
<form method="POST">
@ -68,5 +89,9 @@
</fieldset>
<input class="grd-form-bn grd-form-bn-succeed grd_clickable" type="submit" name="submit" value="&Auml;nderung(en) speichern">
</form>
<% } else if(PAGE_STATE_SUCCEED == state) { %>
<p>Deine Daten werden jetzt mit dem neuen Passwort verschl&uuml;sselt. Du kannst dich in etwa 1 Minute mit deinem neuen Passwort einloggen</p>
<a href="<%= uri_start %>/login" class="grd-form-bn grd-form-bn-succeed">Zum Login</a>
<% } %>
</div>
<%@ include file="footer.cpsp" %>