diff --git a/src/cpp/Crypto/KeyPair.cpp b/src/cpp/Crypto/KeyPair.cpp
index 17aaf87e5..a94fb3f7c 100644
--- a/src/cpp/Crypto/KeyPair.cpp
+++ b/src/cpp/Crypto/KeyPair.cpp
@@ -160,6 +160,16 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, const Mnemonic* wor
return true;
}
+bool KeyPair::generateFromPassphrase(const std::string& passphrase)
+{
+ //static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr);
+ Mnemonic* wordSource = nullptr;
+ if (validatePassphrase(passphrase, &wordSource)) {
+ return generateFromPassphrase(passphrase.data(), wordSource);
+ }
+ return false;
+}
+
MemoryBin* KeyPair::createWordIndices(const std::string& passphrase, const Mnemonic* word_source)
{
auto er = ErrorManager::getInstance();
@@ -366,4 +376,35 @@ bool KeyPair::savePrivKey(int userId)
bool KeyPair::isPubkeysTheSame(const unsigned char* pubkey) const
{
return sodium_memcmp(pubkey, mPublicKey, ed25519_pubkey_SIZE) == 0;
-}
\ No newline at end of file
+}
+
+bool KeyPair::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/)
+{
+ std::istringstream iss(passphrase);
+ std::vector results(std::istream_iterator{iss},
+ std::istream_iterator());
+
+ for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) {
+ Mnemonic& m = ServerConfig::g_Mnemonic_WordLists[i];
+ bool existAll = true;
+ for (auto it = results.begin(); it != results.end(); it++) {
+ if (*it == "\0" || *it == "" || it->size() < 3) continue;
+ if (!m.isWordExist(*it)) {
+ if (i == 1) {
+ int zahl = 0;
+ }
+ //printf("wordlist: %d, word not found: %s\n", i, it->data());
+ existAll = false;
+ continue;
+ }
+ }
+ if (existAll) {
+ if (wordSource) {
+ *wordSource = &m;
+ }
+
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/cpp/Crypto/KeyPair.h b/src/cpp/Crypto/KeyPair.h
index c2a557462..51a7076d2 100644
--- a/src/cpp/Crypto/KeyPair.h
+++ b/src/cpp/Crypto/KeyPair.h
@@ -29,8 +29,10 @@ public:
~KeyPair();
bool generateFromPassphrase(const char* passphrase, const Mnemonic* word_source);
+ bool generateFromPassphrase(const std::string& passphrase);
static std::string passphraseTransform(const std::string& passphrase, const Mnemonic* currentWordSource, const Mnemonic* targetWordSource);
static std::string filterPassphrase(const std::string& passphrase);
+ static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr);
std::string getPubkeyHex();
bool savePrivKey(int userId);
diff --git a/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp
new file mode 100644
index 000000000..d56f16871
--- /dev/null
+++ b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp
@@ -0,0 +1,265 @@
+#include "AdminUserPasswordReset.h"
+#include "Poco/Net/HTTPServerRequest.h"
+#include "Poco/Net/HTTPServerResponse.h"
+#include "Poco/Net/HTMLForm.h"
+#include "Poco/DeflatingStream.h"
+
+
+#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+
+// includes
+#include "../controller/User.h"
+#include "../controller/EmailVerificationCode.h"
+#include "../controller/UserBackups.h"
+
+
+enum PageState
+{
+ PAGE_ASK_EMAIL,
+ PAGE_SHOW_EMAIL
+};
+#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp"
+
+#include "../ServerConfig.h"
+
+
+AdminUserPasswordReset::AdminUserPasswordReset(Session* arg):
+ SessionHTTPRequestHandler(arg)
+{
+}
+
+
+void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)
+{
+ response.setChunkedTransferEncoding(true);
+ response.setContentType("text/html");
+ bool _compressResponse(request.hasToken("Accept-Encoding", "gzip"));
+ if (_compressResponse) response.set("Content-Encoding", "gzip");
+
+ Poco::Net::HTMLForm form(request, request.stream());
+#line 19 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+
+ // code
+ PageState state = PAGE_ASK_EMAIL;
+ Poco::AutoPtr user = controller::User::create();
+ Poco::AutoPtr code;
+ Poco::AutoPtr userBackup;
+ bool validUser = false;
+ std::string pageName = "Admin User Passwort Reset";
+
+ if(!form.empty()) {
+ auto email = form.get("user-email", "");
+
+ if("" != email) {
+ if(1 != user->load(email)) {
+ addError(new Error("Benutzer Email", "Konnte keinen passenden Benutzer finden!"));
+ } else {
+ validUser = true;
+ }
+ }
+ }
+ if(validUser) {
+ auto userId = user->getModel()->getID();
+ code = controller::EmailVerificationCode::load(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD);
+ if(code.isNull()) {
+ code = controller::EmailVerificationCode::create(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD);
+ if(!code->getModel()->insertIntoDB(false)) {
+ addError(new Error("E-Mail Verification Code", "Fehler beim speichern!"));
+ getErrors(code->getModel());
+ }
+ }
+
+ auto backups = controller::UserBackups::load(userId);
+ auto userPubkey = user->getModel()->getPublicKey();
+ for(auto it = backups.begin(); it != backups.end(); it++) {
+ auto keys = (*it)->getKeyPair();
+ if(keys->isPubkeysTheSame(userPubkey)) {
+ userBackup = *it;
+ break;
+ }
+ }
+ if(userBackup.isNull()) {
+ addError(new Error("User Backup", "Kein passendes User Backup gefunden!"));
+ }
+
+ if(!userBackup.isNull() && !code.isNull()) {
+ state = PAGE_SHOW_EMAIL;
+ }
+ }
+
+ std::ostream& _responseStream = response.send();
+ Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1);
+ std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;
+ responseStream << "\n";
+ // begin include header_old.cpsp
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "Gradido Login Server: ";
+#line 9 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp"
+ responseStream << ( pageName );
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\t
Login Server in Entwicklung
\n";
+ responseStream << "\t
Alpha ";
+#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp"
+ responseStream << ( ServerConfig::g_versionString );
+ responseStream << "
\n";
+ responseStream << "
\n";
+ // end include header_old.cpsp
+ responseStream << "\n";
+ responseStream << "\n";
+ responseStream << "\t";
+#line 70 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( getErrorsHtml() );
+ responseStream << "\n";
+ responseStream << "\t
Admin User Passwort Reset
\n";
+ responseStream << "\t
Ein Benutzer hat ein Passwort Reset angefordert, hat aber seine Passphrase nicht.
\n";
+ responseStream << "\t";
+#line 73 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ if(PAGE_ASK_EMAIL == state) { responseStream << "\n";
+ responseStream << "\t\t
\n";
+ responseStream << "\t";
+#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ } responseStream << "\n";
+ responseStream << "\t";
+#line 84 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ if(validUser) {
+ auto userModel = user->getModel(); responseStream << "\n";
+ responseStream << "\t\t
Benutzer gefunden
\n";
+ responseStream << "\t\t
\n";
+ responseStream << "\t\t\t- ";
+#line 88 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( userModel->getFirstName() );
+ responseStream << " ";
+#line 88 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( userModel->getLastName() );
+ responseStream << "
\n";
+ responseStream << "\t\t\t- ";
+#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( userModel->getEmail() );
+ responseStream << "
\n";
+ responseStream << "\t\t\t- Public Key: ";
+#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( userModel->getPublicKeyHex() );
+ responseStream << "
\n";
+ responseStream << "\t\t\t- E-Mail überprüft: ";
+#line 91 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( std::to_string(userModel->isEmailChecked()) );
+ responseStream << "
\n";
+ responseStream << "\t\t\t- Private Key verschlüsselt: ";
+#line 92 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( std::to_string(userModel->existPrivateKeyCrypted()) );
+ responseStream << "
\n";
+ responseStream << "\t\t\t- Passwort gesetzt: ";
+#line 93 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ responseStream << ( std::to_string(userModel->getPasswordHashed() != 0) );
+ responseStream << "
\n";
+ responseStream << "\t\t
\n";
+ responseStream << "\t";
+#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ } responseStream << "\n";
+ responseStream << "\t";
+#line 96 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ if(PAGE_SHOW_EMAIL == state) { responseStream << "\n";
+ responseStream << "\t\t
\n";
+ responseStream << "\t";
+#line 115 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+ } responseStream << "\n";
+ responseStream << "
\n";
+ // begin include footer.cpsp
+ responseStream << "\t\n";
+ responseStream << "\t\t\t";
+#line 2 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp"
+ responseStream << ( mTimeProfiler.string() );
+ responseStream << "\n";
+ responseStream << "\t
\n";
+ responseStream << "\n";
+ responseStream << "";
+ // end include footer.cpsp
+ responseStream << "\n";
+ responseStream << "\t\n";
+ if (_compressResponse) _gzipStream.close();
+}
diff --git a/src/cpp/HTTPInterface/AdminUserPasswordReset.h b/src/cpp/HTTPInterface/AdminUserPasswordReset.h
new file mode 100644
index 000000000..12ebbf3ca
--- /dev/null
+++ b/src/cpp/HTTPInterface/AdminUserPasswordReset.h
@@ -0,0 +1,20 @@
+#ifndef AdminUserPasswordReset_INCLUDED
+#define AdminUserPasswordReset_INCLUDED
+
+
+#include "Poco/Net/HTTPRequestHandler.h"
+
+
+#include "SessionHTTPRequestHandler.h"
+
+
+class AdminUserPasswordReset: public SessionHTTPRequestHandler
+{
+public:
+ AdminUserPasswordReset(Session*);
+
+ void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
+};
+
+
+#endif // AdminUserPasswordReset_INCLUDED
diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp
index bc2d7a62c..3a8617136 100644
--- a/src/cpp/controller/User.cpp
+++ b/src/cpp/controller/User.cpp
@@ -92,6 +92,14 @@ namespace controller {
return mPublicHex;
}
+ std::string User::getEmailWithNames()
+ {
+ std::stringstream ss;
+ auto model = getModel();
+ ss << model->getFirstName() << " " << model->getLastName() << "<" << model->getEmail() << ">";
+ return ss.str();
+ }
+
Poco::JSON::Object User::getJson()
{
auto json = getModel()->getJson();
diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h
index b8ac5f45f..fdfbddf57 100644
--- a/src/cpp/controller/User.h
+++ b/src/cpp/controller/User.h
@@ -35,7 +35,7 @@ namespace controller {
inline const model::table::User* getModel() const { return _getModel(); }
-
+ std::string getEmailWithNames();
const std::string& getPublicHex();
diff --git a/src/cpp/controller/UserBackups.cpp b/src/cpp/controller/UserBackups.cpp
index ca3e17207..0d9a408a1 100644
--- a/src/cpp/controller/UserBackups.cpp
+++ b/src/cpp/controller/UserBackups.cpp
@@ -46,4 +46,42 @@ namespace controller {
}
+ Poco::SharedPtr UserBackups::getKeyPair()
+ {
+ if (!mKeyPair.isNull()) {
+ return mKeyPair;
+ }
+ mKeyPair = new KeyPair;
+ auto model = getModel();
+ auto passphrase = model->getPassphrase();
+
+ mKeyPair->generateFromPassphrase(passphrase);
+ return mKeyPair;
+ }
+
+ std::string UserBackups::getPassphrase(ServerConfig::Mnemonic_Types type)
+ {
+ if ((int)type < 0 || (int)type >= ServerConfig::Mnemonic_Types::MNEMONIC_MAX) {
+ return "";
+ }
+ auto passphrase = getModel()->getPassphrase();
+ Mnemonic* wordSource = nullptr;
+ if (KeyPair::validatePassphrase(passphrase, &wordSource)) {
+ for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) {
+ Mnemonic* m = &ServerConfig::g_Mnemonic_WordLists[i];
+ if (m == wordSource) {
+ if (type == i) {
+ return passphrase;
+ }
+ else {
+ return KeyPair::passphraseTransform(passphrase, m, &ServerConfig::g_Mnemonic_WordLists[type]);
+ }
+ }
+ }
+ }
+ else {
+ return "";
+ }
+ }
+
}
\ No newline at end of file
diff --git a/src/cpp/controller/UserBackups.h b/src/cpp/controller/UserBackups.h
index b55adaa9f..780207a9d 100644
--- a/src/cpp/controller/UserBackups.h
+++ b/src/cpp/controller/UserBackups.h
@@ -2,6 +2,9 @@
#define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE
#include "../model/table/UserBackups.h"
+#include "../Crypto/KeyPair.h"
+
+#include "Poco/SharedPtr.h"
#include "TableControllerBase.h"
@@ -20,10 +23,13 @@ namespace controller {
inline Poco::AutoPtr getModel() { return _getModel(); }
+ //! \return create keyPair from passphrase if not exist, else return existing pointer
+ Poco::SharedPtr getKeyPair();
+ std::string getPassphrase(ServerConfig::Mnemonic_Types type);
protected:
UserBackups(model::table::UserBackups* dbModel);
-
+ Poco::SharedPtr mKeyPair;
};
}
diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp
index fff3c1a9f..212a8ab69 100644
--- a/src/cpp/model/User.cpp
+++ b/src/cpp/model/User.cpp
@@ -550,33 +550,8 @@ std::string User::generateNewPassphrase(Mnemonic* word_source)
bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/)
{
- std::istringstream iss(passphrase);
- std::vector results(std::istream_iterator{iss},
- std::istream_iterator());
+ return KeyPair::validatePassphrase(passphrase, wordSource);
- for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) {
- Mnemonic& m = ServerConfig::g_Mnemonic_WordLists[i];
- bool existAll = true;
- for (auto it = results.begin(); it != results.end(); it++) {
- if (*it == "\0" || *it == "" || it->size() < 3) continue;
- if (!m.isWordExist(*it)) {
- if (i == 1) {
- int zahl = 0;
- }
- //printf("wordlist: %d, word not found: %s\n", i, it->data());
- existAll = false;
- continue;
- }
- }
- if (existAll) {
- if (wordSource) {
- *wordSource = &m;
- }
-
- return true;
- }
- }
- return false;
}
bool User::isEmptyPassword()
diff --git a/src/cpp/model/email/EmailModificate.cpp b/src/cpp/model/email/EmailModificate.cpp
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/cpp/model/email/EmailModificate.h b/src/cpp/model/email/EmailModificate.h
new file mode 100644
index 000000000..a87287b79
--- /dev/null
+++ b/src/cpp/model/email/EmailModificate.h
@@ -0,0 +1,12 @@
+/*!
+*
+* \author: einhornimmond
+*
+* \date: 22.04.20
+*
+* \brief: make email modificateable
+*/
+
+
+namespace model {
+}
\ No newline at end of file
diff --git a/src/cpsp/PassphrasedTransaction.cpsp b/src/cpsp/PassphrasedTransaction.cpsp
index 5f7e4b8a0..debc1f296 100644
--- a/src/cpsp/PassphrasedTransaction.cpsp
+++ b/src/cpsp/PassphrasedTransaction.cpsp
@@ -153,6 +153,7 @@ enum PageState {
+
<% } else if(PAGE_STATE_SUCCESS == state) { %>
Gradidos wurden erfolgreich überwiesen.
Weitere Gradidos überweisen
diff --git a/src/cpsp/adminUserPasswordReset.cpsp b/src/cpsp/adminUserPasswordReset.cpsp
new file mode 100644
index 000000000..870e044d7
--- /dev/null
+++ b/src/cpsp/adminUserPasswordReset.cpsp
@@ -0,0 +1,118 @@
+<%@ page class="AdminUserPasswordReset" %>
+<%@ page form="true" %>
+<%@ page compressed="true" %>
+<%@ page baseClass="SessionHTTPRequestHandler" %>
+<%@ page ctorArg="Session*" %>
+<%@ header include="SessionHTTPRequestHandler.h" %>
+<%!
+// includes
+#include "../controller/User.h"
+#include "../controller/EmailVerificationCode.h"
+#include "../controller/UserBackups.h"
+
+
+enum PageState
+{
+ PAGE_ASK_EMAIL,
+ PAGE_SHOW_EMAIL
+};
+%><%%
+ // code
+ PageState state = PAGE_ASK_EMAIL;
+ Poco::AutoPtr user = controller::User::create();
+ Poco::AutoPtr code;
+ Poco::AutoPtr userBackup;
+ bool validUser = false;
+ std::string pageName = "Admin User Passwort Reset";
+
+ if(!form.empty()) {
+ auto email = form.get("user-email", "");
+
+ if("" != email) {
+ if(1 != user->load(email)) {
+ addError(new Error("Benutzer Email", "Konnte keinen passenden Benutzer finden!"));
+ } else {
+ validUser = true;
+ }
+ }
+ }
+ if(validUser) {
+ auto userId = user->getModel()->getID();
+ code = controller::EmailVerificationCode::load(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD);
+ if(code.isNull()) {
+ code = controller::EmailVerificationCode::create(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD);
+ if(!code->getModel()->insertIntoDB(false)) {
+ addError(new Error("E-Mail Verification Code", "Fehler beim speichern!"));
+ getErrors(code->getModel());
+ }
+ }
+
+ auto backups = controller::UserBackups::load(userId);
+ auto userPubkey = user->getModel()->getPublicKey();
+ for(auto it = backups.begin(); it != backups.end(); it++) {
+ auto keys = (*it)->getKeyPair();
+ if(keys->isPubkeysTheSame(userPubkey)) {
+ userBackup = *it;
+ break;
+ }
+ }
+ if(userBackup.isNull()) {
+ addError(new Error("User Backup", "Kein passendes User Backup gefunden!"));
+ }
+
+ if(!userBackup.isNull() && !code.isNull()) {
+ state = PAGE_SHOW_EMAIL;
+ }
+ }
+
+%><%@ include file="header_old.cpsp" %>
+
+ <%= getErrorsHtml() %>
+
Admin User Passwort Reset
+
Ein Benutzer hat ein Passwort Reset angefordert, hat aber seine Passphrase nicht.
+ <% if(PAGE_ASK_EMAIL == state) { %>
+
+ <% } %>
+ <% if(validUser) {
+ auto userModel = user->getModel(); %>
+
Benutzer gefunden
+
+ - <%= userModel->getFirstName() %> <%= userModel->getLastName() %>
+ - <%= userModel->getEmail() %>
+ - Public Key: <%= userModel->getPublicKeyHex() %>
+ - E-Mail überprüft: <%= std::to_string(userModel->isEmailChecked()) %>
+ - Private Key verschlüsselt: <%= std::to_string(userModel->existPrivateKeyCrypted()) %>
+ - Passwort gesetzt: <%= std::to_string(userModel->getPasswordHashed() != 0) %>
+
+ <% } %>
+ <% if(PAGE_SHOW_EMAIL == state) { %>
+
+ <% } %>
+
+<%@ include file="footer.cpsp" %>
+