diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 756cb2c61..d404662bd 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -99,7 +99,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: auto uri_start = request.serverParams().getServerName(); auto lastExternReferer = mSession->getLastReferer(); - + printf("user state: %d\n", userState); switch(userState) { case USER_EMPTY: case USER_PASSWORD_INCORRECT: @@ -108,6 +108,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: case USER_PASSWORD_ENCRYPTION_IN_PROCESS: addError(new Error(langCatalog->gettext("Passwort"), langCatalog->gettext("Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut.")), false); break; + /* case USER_EMAIL_NOT_ACTIVATED: mSession->addError(new Error(langCatalog->gettext("Account"), langCatalog->gettext("E-Mail Address not checked, do you already get one?")), false); response.redirect(ServerConfig::g_serverPath + "/checkEmail"); @@ -121,11 +122,16 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: } response.redirect(ServerConfig::g_serverPath + "/passphrase"); return; + */ case USER_KEYS_DONT_MATCH: addError(new Error(langCatalog->gettext("User"), langCatalog->gettext("Error in saved data, the server admin will look at it."))); break; + case USER_NO_KEYS: + mSession->generateKeys(true, true); + // no break, correct, if user has no keys, he will be redirect also to dashboard after login case USER_NO_PRIVATE_KEY: case USER_COMPLETE: + case USER_EMAIL_NOT_ACTIVATED: auto referer = request.find("Referer"); std::string refererString; if (referer != request.end()) { @@ -225,20 +231,20 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "
\n"; responseStream << " \n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t \n"; responseStream << "\t\t\t\t\"logo\"\n"; responseStream << "\t\t\t\n"; @@ -250,14 +256,14 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t\t"; -#line 168 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\t \n"; responseStream << "\t\t\t
\n"; responseStream << "
\n"; responseStream << " \n"; responseStream << "\t\t\t \n"; responseStream << "\t\t\t "; @@ -297,46 +303,46 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: // end include flags.cpsp responseStream << "\n"; responseStream << "\t\t\t
\n"; responseStream << "
\n"; responseStream << "
\n"; responseStream << "
\n"; responseStream << " gettext("E-Mail") ); responseStream << "\" value=\""; -#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( presetEmail ); responseStream << "\"/>\n"; responseStream << "
\n"; responseStream << "
\n"; responseStream << " gettext("Password") ); responseStream << "\" />\n"; responseStream << "
\n"; responseStream << " \n"; responseStream << "
\n"; responseStream << "\t\t\t\t\t\n"; diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 478b31e54..4437e5c9e 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -167,13 +167,19 @@ namespace controller { return 0; } - void User::setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair) + int User::setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair) { assert(gradidoKeyPair); std::unique_lock _lock(mSharedMutex); if (mGradidoKeyPair) delete mGradidoKeyPair; mGradidoKeyPair = gradidoKeyPair; getModel()->setPublicKey(mGradidoKeyPair->getPublicKey()); + if (mPassword && mPassword->hasKey()) { + auto model = getModel(); + model->setPrivateKey(mGradidoKeyPair->getCryptedPrivKey(mPassword)); + return 1; + } + return 0; } int User::setPassword(AuthenticatedEncryption* passwd) diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index f9f98cac3..6033c4e68 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -73,9 +73,11 @@ namespace controller { std::shared_lock _lock(mSharedMutex); return mPassword; } - //! \brief set key pair, public in model, private with next setPassword call into model + //! \brief set key pair, public in model, private if password exist else with next setPassword call into model //! \param gradidoKeyPair take owner ship - void setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair); + //! \param return 0 if public key set + //! \param return 1 if also private key set (and password exist) + int setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair); inline const KeyPairEd25519* getGradidoKeyPair() { std::shared_lock _lock(mSharedMutex); diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 2c020b840..69de34e18 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -367,20 +367,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string& } } - // passphrase - auto passphrase = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES]); - if (passphrase.isNull()) { - em->addError(new ParamError(function_name, "error generating passphrase for", email)); - em->sendErrorsAsEmail(); - } - auto user_backup = controller::UserBackups::create(user_id, passphrase->getString()); - user_backup->getModel()->insertIntoDB(false); - - // keys - auto gradido_key_pair = KeyPairEd25519::create(passphrase); - mNewUser->setGradidoKeyPair(gradido_key_pair); - // save pubkey in db - user_model->updatePublickey(); + generateKeys(true, true); // calculate encryption key, could need some time, will save encrypted privkey to db UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(mNewUser, password); @@ -1074,6 +1061,8 @@ bool Session::useOrGeneratePassphrase(const std::string& passphase) */ bool Session::generatePassphrase() { + if (mNewUser.isNull()) return false; + auto lang = getLanguage(); if (lang == LANG_EN) { mPassphrase = User::generateNewPassphrase(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER]); @@ -1088,6 +1077,57 @@ bool Session::generatePassphrase() bool Session::generateKeys(bool savePrivkey, bool savePassphrase) { + if (mNewUser.isNull()) { + addError(new Error(gettext("Benutzer"), gettext("Kein gültiger Benutzer, bitte logge dich erneut ein."))); + return false; + } + static const char* function_name = "Session::generateKeys"; + auto lang = getLanguage(); + auto user_model = mNewUser->getModel(); + auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + if (LANG_DE == lang) { + mnemonic_type = ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES; + } + + auto passphrase = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + if (!passphrase) { + addError(new ParamError(function_name, "Error generating passphrase with mnemonic: ", mnemonic_type)); + addError(new ParamError(function_name, "user email: ", mNewUser->getModel()->getEmail())); + sendErrorsAsEmail(); + addError(new Error(gettext("Benutzer"), gettext("Fehler beim generieren der Passphrase, der Admin bekommt eine E-Mail. "))); + return false; + } + + if (savePassphrase) { + auto user_backup = controller::UserBackups::create(user_model->getID(), passphrase->getString()); + // sync version + //user_backup->getModel()->insertIntoDB(false); + + // async version + UniLib::controller::TaskPtr save_user_backup_task = new model::table::ModelInsertTask(user_backup->getModel(), false, true); + save_user_backup_task->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_PASSPHRASE_WRITTEN, this)); + save_user_backup_task->scheduleTask(save_user_backup_task); + } + + // keys + auto gradido_key_pair = KeyPairEd25519::create(passphrase); + auto set_key_result = mNewUser->setGradidoKeyPair(gradido_key_pair); + if (1 == set_key_result && savePrivkey) { + // save public key and private key in db + user_model->updatePubkeyAndPrivkey(); + } + else { + // save public key in db + user_model->updatePublickey(); + } + if (user_model->errorCount()) { + user_model->sendErrorsAsEmail(); + addError(new Error(gettext("Benutzer"), gettext("Fehler beim speichern der Keys, der Admin bekommt eine E-Mail. "))); + return false; + } + return true; + /* + bool validUser = true; if (mSessionUser) { if (!mSessionUser->generateKeys(savePrivkey, mPassphrase, this)) { @@ -1113,4 +1153,5 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase) mPassphrase.clear(); return true; + */ } diff --git a/src/cpp/model/Session.h b/src/cpp/model/Session.h index 6cf1a0cb7..fc7f0e83a 100644 --- a/src/cpp/model/Session.h +++ b/src/cpp/model/Session.h @@ -80,6 +80,7 @@ public: //! \brief new register function, without showing user pubkeys, using controller/user bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password); + // adminRegister without passwort bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email); diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index a407c4cf7..26947da8c 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -193,6 +193,36 @@ namespace model { return 0; } + size_t User::updatePubkeyAndPrivkey() + { + lock(); + if (mPrivateKey.isNull() || !mPublicKey || !mID) { + unlock(); + return 0; + } + auto cm = ConnectionManager::getInstance(); + auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER); + + Poco::Data::Statement update(session); + + update << "UPDATE users SET pubkey = ?, privkey = ? where id = ?;", + use(mPublicKey), use(mPrivateKey), use(mID); + + + size_t resultCount = 0; + try { + return update.execute(); + } + catch (Poco::Exception& ex) { + lock("User::updatePrivkeyAndPasswordHash"); + addError(new ParamError(getTableName(), "mysql error by insert", ex.displayText().data())); + addError(new ParamError(getTableName(), "data set: ", toString().data())); + unlock(); + } + //printf("data valid: %s\n", toString().data()); + return 0; + } + /* std::string mEmail; diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index 6e6b6f86f..8e72cbbe6 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -46,6 +46,7 @@ namespace model { size_t updatePrivkey(); size_t updatePublickey(); size_t updatePrivkeyAndPasswordHash(); + size_t updatePubkeyAndPrivkey(); // default getter unlocked inline const std::string& getEmail() const { return mEmail; } diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index c32381745..f7462b757 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -78,7 +78,7 @@ auto uri_start = request.serverParams().getServerName(); auto lastExternReferer = mSession->getLastReferer(); - + printf("user state: %d\n", userState); switch(userState) { case USER_EMPTY: case USER_PASSWORD_INCORRECT: @@ -87,6 +87,7 @@ case USER_PASSWORD_ENCRYPTION_IN_PROCESS: addError(new Error(langCatalog->gettext("Passwort"), langCatalog->gettext("Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut.")), false); break; + /* case USER_EMAIL_NOT_ACTIVATED: mSession->addError(new Error(langCatalog->gettext("Account"), langCatalog->gettext("E-Mail Address not checked, do you already get one?")), false); response.redirect(ServerConfig::g_serverPath + "/checkEmail"); @@ -100,11 +101,16 @@ } response.redirect(ServerConfig::g_serverPath + "/passphrase"); return; + */ case USER_KEYS_DONT_MATCH: addError(new Error(langCatalog->gettext("User"), langCatalog->gettext("Error in saved data, the server admin will look at it."))); break; + case USER_NO_KEYS: + mSession->generateKeys(true, true); + // no break, correct, if user has no keys, he will be redirect also to dashboard after login case USER_NO_PRIVATE_KEY: case USER_COMPLETE: + case USER_EMAIL_NOT_ACTIVATED: auto referer = request.find("Referer"); std::string refererString; if (referer != request.end()) { diff --git a/src/cpsp/registerDirect.cpsp b/src/cpsp/registerDirect.cpsp index ac8ddab35..3ea850be4 100644 --- a/src/cpsp/registerDirect.cpsp +++ b/src/cpsp/registerDirect.cpsp @@ -32,6 +32,10 @@ form.get("register-password", "") ); getErrors(session); + if(!errorCount()) { + response.redirect(ServerConfig::g_php_serverPath + "/"); + return; + } } } else { @@ -43,14 +47,6 @@

Einen neuen Account anlegen

<%= getErrorsHtml() %> - <% if(!form.empty() && userReturned) {%> -
-
- Deine Anmeldung wird verarbeitet und es wird dir eine E-Mail zugeschickt. - Wenn sie da ist, befolge ihren Anweisungen. -
-
- <% } else { %>
@@ -80,6 +76,5 @@ - <% } %>
<%@ include file="footer.cpsp" %>