update session generate keys, move call into function

This commit is contained in:
Dario 2020-06-18 07:48:46 +02:00
parent 57cada7252
commit 939e1dd9d0
9 changed files with 131 additions and 43 deletions

View File

@ -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 << " <div class=\"row\">\n";
responseStream << " <div class=\"col-12 logo-section\">\n";
responseStream << " <a href=\"";
#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 161 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "\" class=\"logo\">\n";
responseStream << "\t\t\t<picture>\n";
responseStream << "\t\t\t\t<source srcset=\"";
#line 157 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 163 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "img/logo_schrift.webp\" type=\"image/webp\">\n";
responseStream << "\t\t\t\t<source srcset=\"";
#line 158 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "img/logo_schrift.png\" type=\"image/png\"> \n";
responseStream << "\t\t\t\t<img src=\"";
#line 159 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 165 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "img/logo_schrift.png\" alt=\"logo\" />\n";
responseStream << "\t\t\t</picture>\n";
@ -250,14 +256,14 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::
responseStream << " <div class=\"grid\">\n";
responseStream << "\t\t\t<div class=\"center-ul-container\">\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</div>\n";
responseStream << " <div class=\"grid-body\">\n";
responseStream << " \n";
responseStream << "\t\t\t <!--<input type=\"hidden\" name=\"lang\" value=\"";
#line 172 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( LanguageManager::keyForLanguage(lang) );
responseStream << "\">-->\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 <form action=\"";
#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/\" method=\"POST\">\n";
responseStream << " <div class=\"row display-block\">\n";
responseStream << " <div class=\"col-lg-7 col-md-8 col-sm-9 col-12 mx-auto form-wrapper\">\n";
responseStream << " <div class=\"form-group input-rounded\">\n";
responseStream << " <input type=\"text\" class=\"form-control\" name=\"login-email\" placeholder=\"";
#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( langCatalog->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 << " </div>\n";
responseStream << " <div class=\"form-group input-rounded\">\n";
responseStream << " <input type=\"password\" class=\"form-control\" name=\"login-password\" placeholder=\"";
#line 181 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( langCatalog->gettext("Password") );
responseStream << "\" />\n";
responseStream << " </div>\n";
responseStream << " <button type=\"submit\" name=\"submit\" class=\"btn btn-primary btn-block\">";
#line 183 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 189 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( langCatalog->gettext(" Login ") );
responseStream << "</button>\n";
responseStream << " <div class=\"signup-link\">\n";
responseStream << " <p>";
#line 185 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 191 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( langCatalog->gettext("You haven't any account yet? Please follow the link to create one.") );
responseStream << "</p>\n";
responseStream << " <a href=\"https://gradido.com\">";
#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 192 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( langCatalog->gettext("Create New Account") );
responseStream << "</a>\n";
responseStream << " </div>\n";
responseStream << "\t\t\t\t\t<div class=\"reset-pwd-link\">\n";
responseStream << "\t\t\t\t\t\t<a href=\"";
#line 189 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/resetPassword\">";
#line 189 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp"
responseStream << ( langCatalog->gettext("Passwort vergessen") );
responseStream << "</a>\n";
responseStream << "\t\t\t\t\t</div>\n";

View File

@ -167,13 +167,19 @@ namespace controller {
return 0;
}
void User::setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair)
int User::setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair)
{
assert(gradidoKeyPair);
std::unique_lock<std::shared_mutex> _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)

View File

@ -73,9 +73,11 @@ namespace controller {
std::shared_lock<std::shared_mutex> _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<std::shared_mutex> _lock(mSharedMutex);

View File

@ -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&uuml;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;
*/
}

View File

@ -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);

View File

@ -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;

View File

@ -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; }

View File

@ -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()) {

View File

@ -32,6 +32,10 @@
form.get("register-password", "")
);
getErrors(session);
if(!errorCount()) {
response.redirect(ServerConfig::g_php_serverPath + "/");
return;
}
}
} else {
@ -43,14 +47,6 @@
<div class="grd_container">
<h1>Einen neuen Account anlegen</h1>
<%= getErrorsHtml() %>
<% if(!form.empty() && userReturned) {%>
<div class="grd_text-max-width">
<div class="grd_text">
Deine Anmeldung wird verarbeitet und es wird dir eine E-Mail zugeschickt.
Wenn sie da ist, befolge ihren Anweisungen.
</div>
</div>
<% } else { %>
<form method="POST">
<fieldset class="grd_container_small">
@ -80,6 +76,5 @@
<input class="grd-form-bn grd-form-bn-succeed" type="submit" name="submit" value="Anmelden">
</form>
<% } %>
</div>
<%@ include file="footer.cpsp" %>