diff --git a/src/cpp/Crypto/KeyPair.cpp b/src/cpp/Crypto/KeyPair.cpp index 5c177fe6f..61d98470f 100644 --- a/src/cpp/Crypto/KeyPair.cpp +++ b/src/cpp/Crypto/KeyPair.cpp @@ -43,8 +43,8 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour // libsodium doc: https://libsodium.gitbook.io/doc/advanced/hmac-sha2 // https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki //crypto_auth_hmacsha512_keygen - unsigned long word_indices[PHRASE_WORD_COUNT+1]; - memset(word_indices, 0, PHRASE_WORD_COUNT + 1); + unsigned long word_indices[PHRASE_WORD_COUNT]; + memset(word_indices, 0, PHRASE_WORD_COUNT); //DHASH key = DRMakeStringHash(passphrase); size_t pass_phrase_size = strlen(passphrase); @@ -96,8 +96,10 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour /*printf("word_indices: \n"); for (int i = 0; i < PHRASE_WORD_COUNT; i++) { if (i > 0) printf(" "); - printf("%hu", word_indices[i]); - }//*/ + printf("%4hu", word_indices[i]); + } + printf("\n"); + //*/ //printf("\nclear passphrase: \n%s\n", clearPassphrase.data()); // printf("passphrase bin: \n%s\n\n", getHex((unsigned char*)passphrase, pass_phrase_size).data()); @@ -248,4 +250,9 @@ bool KeyPair::savePrivKey(int userId) return false; } return true; +} + +bool KeyPair::isPubkeysTheSame(const unsigned char* pubkey) const +{ + return sodium_memcmp(pubkey, mPublicKey, ed25519_pubkey_SIZE) == 0; } \ No newline at end of file diff --git a/src/cpp/Crypto/KeyPair.h b/src/cpp/Crypto/KeyPair.h index cde5f0a9a..3445f69bd 100644 --- a/src/cpp/Crypto/KeyPair.h +++ b/src/cpp/Crypto/KeyPair.h @@ -32,6 +32,8 @@ public: inline const unsigned char* getPublicKey() const { return mSodiumPublic; } + bool isPubkeysTheSame(const unsigned char* pubkey) const; + protected: const MemoryBin* getPrivateKey() const { return mSodiumSecret; } diff --git a/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp b/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp new file mode 100644 index 000000000..a0d0a6af3 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminCheckUserBackup.cpp @@ -0,0 +1,223 @@ +#include "AdminCheckUserBackup.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\\adminCheckUserBackup.cpsp" + +#include "../crypto/KeyPair.h" +#include "../SingletonManager/ConnectionManager.h" + +#include "../controller/UserBackups.h" + +#include "Poco/Data/Binding.h" +using namespace Poco::Data::Keywords; + +typedef Poco::Tuple, std::string> UserBackupTuple; + +struct SListEntry +{ + Poco::AutoPtr user; + std::vector> backups; +}; + +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" + +#include "../ServerConfig.h" + + +AdminCheckUserBackup::AdminCheckUserBackup(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminCheckUserBackup::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 25 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + + const char* pageName = "Admin Check User Backups"; + auto cm = ConnectionManager::getInstance(); + KeyPair keys; + std::list notMatchingEntrys; + + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + std::list userBackupEntrys; + select << "SELECT u.id, u.pubkey, b.passphrase FROM users as u LEFT JOIN user_backups as b on(u.id = b.user_id)" + , into(userBackupEntrys); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + + for(auto it = userBackupEntrys.begin(); it != userBackupEntrys.end(); it++) { + auto tuple = *it; + auto pubkey = tuple.get<1>(); + if(pubkey.isNull()) { + continue; + } + auto passphrase = KeyPair::filterPassphrase(tuple.get<2>()); + auto user_id = tuple.get<0>(); + Mnemonic* wordSource = nullptr; + if(!User::validatePassphrase(passphrase, &wordSource)) { + addError(new Error("admin Check user backup", "invalid passphrase")); + addError(new ParamError("admin Check user backup", "passphrase", passphrase.data())); + addError(new ParamError("admin Check user backup", "user id", user_id)); + continue; + } else { + keys.generateFromPassphrase(passphrase.data(), wordSource); + } + if(keys.isPubkeysTheSame(pubkey.value().content().data())) { + continue; + } + SListEntry entry; + entry.user = controller::User::create(); + entry.user->load(user_id); + entry.backups = controller::UserBackups::load(user_id); + + notMatchingEntrys.push_back(entry); + + } + } + catch (Poco::Exception& ex) { + addError(new ParamError("adminCheckUserBackup", "mysql error", ex.displayText().data())); + } + + + + 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

Admin Check User Backup

\n"; + responseStream << "\t"; +#line 78 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "\t

Unmatching count: "; +#line 79 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( notMatchingEntrys.size() ); + responseStream << "

\n"; + responseStream << "\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t\t\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t\t\n"; + responseStream << "\t\t\t"; +#line 85 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + for(auto it = notMatchingEntrys.begin(); it != notMatchingEntrys.end(); it++) { + auto userModel = (*it).user->getModel(); + responseStream << "\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t"; +#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\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"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminCheckUserBackup.h b/src/cpp/HTTPInterface/AdminCheckUserBackup.h new file mode 100644 index 000000000..fac65cdb0 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminCheckUserBackup.h @@ -0,0 +1,20 @@ +#ifndef AdminCheckUserBackup_INCLUDED +#define AdminCheckUserBackup_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminCheckUserBackup: public SessionHTTPRequestHandler +{ +public: + AdminCheckUserBackup(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminCheckUserBackup_INCLUDED diff --git a/src/cpp/HTTPInterface/DebugPassphrasePage.cpp b/src/cpp/HTTPInterface/DebugPassphrasePage.cpp index 32f3b589c..6bd01fc1c 100644 --- a/src/cpp/HTTPInterface/DebugPassphrasePage.cpp +++ b/src/cpp/HTTPInterface/DebugPassphrasePage.cpp @@ -35,6 +35,7 @@ void DebugPassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, P std::string privKeyHex = ""; std::string privKeyCryptedHex = ""; User::passwordHashed pwdHashed = 0; + Poco::AutoPtr existingUser; if(!form.empty()) { auto passphrase = KeyPair::filterPassphrase(form.get("passphrase", "")); Mnemonic* wordSource = nullptr; @@ -43,7 +44,14 @@ void DebugPassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, P } else { keys.generateFromPassphrase(passphrase.data(), wordSource); } - auto newUser = new User(form.get("email", "").data(), "first_name", "last_name"); + auto email = form.get("email", ""); + auto newUser = new User(email.data(), "first_name", "last_name"); + + + if(email != "") { + existingUser = controller::User::create(); + existingUser->load(email); + } newUser->validatePwd(form.get("password", ""), this); pwdHashed = newUser->getPwdHashed(); auto privKey = keys.getPrivateKey(); @@ -131,7 +139,7 @@ void DebugPassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "
\n"; responseStream << "\t

Debug Passphrase

\n"; responseStream << "\t"; -#line 45 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" +#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "\t
\n"; @@ -140,7 +148,7 @@ void DebugPassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\t\t\t

\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t

\n"; @@ -149,28 +157,41 @@ void DebugPassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, P responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t

\n"; responseStream << "\t\t\t\n"; responseStream << "\t\t\n"; responseStream << "\t\t\n"; responseStream << "\t\n"; responseStream << "\t

Public key:
"; -#line 61 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" +#line 69 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" responseStream << ( keys.getPubkeyHex() ); responseStream << "

\n"; responseStream << "\t

Private Key:
"; -#line 62 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" +#line 70 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" responseStream << ( privKeyHex ); responseStream << "

\n"; responseStream << "\t

Passwort Hashed:
"; -#line 63 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" +#line 71 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" responseStream << ( std::to_string(pwdHashed) ); responseStream << "

\n"; responseStream << "\t

Private key crypted:
"; -#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" +#line 72 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" responseStream << ( privKeyCryptedHex ); responseStream << "

\n"; + responseStream << "\t"; +#line 73 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" + if(!existingUser.isNull()) { + auto userModel = existingUser->getModel(); + auto dbPubkey = userModel->getPublicKey(); + responseStream << "\n"; + responseStream << "\t\t

user Public:
"; +#line 77 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" + responseStream << ( KeyPair::getHex(dbPubkey, ed25519_pubkey_SIZE) ); + responseStream << "

\n"; + responseStream << "\t"; +#line 78 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\debugPassphrase.cpsp" + } responseStream << "\n"; responseStream << "
\n"; // begin include footer.cpsp responseStream << "\t
\n"; diff --git a/src/cpp/HTTPInterface/LoginPage.cpp b/src/cpp/HTTPInterface/LoginPage.cpp index 7c4d38d5f..580e80798 100644 --- a/src/cpp/HTTPInterface/LoginPage.cpp +++ b/src/cpp/HTTPInterface/LoginPage.cpp @@ -118,8 +118,15 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: return; case USER_NO_PRIVATE_KEY: case USER_COMPLETE: + auto referer = request.find("Referer"); + std::string refererString; + if (referer != request.end()) { + refererString = referer->second; + } if(lastExternReferer != "") { response.redirect(lastExternReferer); + } else if(refererString != "") { + response.redirect(refererString); } else { response.redirect(ServerConfig::g_php_serverPath + "/"); } @@ -196,20 +203,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"; @@ -221,29 +228,29 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t\t"; -#line 150 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 157 "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 << "
\n"; responseStream << "
\n"; responseStream << "
\n"; responseStream << " \n"; @@ -252,12 +259,12 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "
\n"; responseStream << " \n"; @@ -268,39 +275,39 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net:: responseStream << "
\n"; responseStream << "
\n"; responseStream << " gettext("E-Mail") ); responseStream << "\" value=\""; -#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 183 "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 << "

"; -#line 183 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 190 "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 << "

\n"; responseStream << " "; -#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" +#line 191 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp" responseStream << ( langCatalog->gettext("Create New Account") ); responseStream << "\n"; responseStream << "
\n"; responseStream << "\t\t\t\t\t
\n"; diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index f9b277dff..1982ec801 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -20,6 +20,7 @@ #include "ResetPassword.h" #include "RegisterAdminPage.h" #include "DebugPassphrasePage.h" +#include "AdminCheckUserBackup.h" #include "DecodeTransactionPage.h" @@ -144,6 +145,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/checkUserBackups") { + auto pageRequestHandler = new AdminCheckUserBackup(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } } if(url_first_part == "/logout") { diff --git a/src/cpp/controller/EmailVerificationCode.h b/src/cpp/controller/EmailVerificationCode.h index 3bcecaa33..893dd15ac 100644 --- a/src/cpp/controller/EmailVerificationCode.h +++ b/src/cpp/controller/EmailVerificationCode.h @@ -1,5 +1,5 @@ -#ifndef GRADIDO_LOGIN_SERVER_MODEL_EMAIL_VERIFICATION_CODE_INCLUDE -#define GRADIDO_LOGIN_SERVER_MODEL_EMAIL_VERIFICATION_CODE_INCLUDE +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_EMAIL_VERIFICATION_CODE_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_EMAIL_VERIFICATION_CODE_INCLUDE #include "../model/table/EmailOptIn.h" @@ -33,4 +33,4 @@ namespace controller { }; } -#endif //GRADIDO_LOGIN_SERVER_MODEL_EMAIL_VERIFICATION_CODE_INCLUDE \ No newline at end of file +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_EMAIL_VERIFICATION_CODE_INCLUDE \ No newline at end of file diff --git a/src/cpp/controller/UserBackups.cpp b/src/cpp/controller/UserBackups.cpp new file mode 100644 index 000000000..ca3e17207 --- /dev/null +++ b/src/cpp/controller/UserBackups.cpp @@ -0,0 +1,49 @@ +#include "UserBackups.h" + +namespace controller { + UserBackups::UserBackups(model::table::UserBackups* dbModel) + { + mDBModel = dbModel; + } + + UserBackups::~UserBackups() + { + + } + + + + // --------------- static members ----------------------------- + + Poco::AutoPtr UserBackups::create(int user_id, const std::string& passphrase) + { + + auto db = new model::table::UserBackups(user_id, passphrase); + return Poco::AutoPtr(new UserBackups(db)); + } + + + std::vector> UserBackups::load(int user_id) + { + auto db = new model::table::UserBackups(); + auto results = db->loadFromDB("user_id", user_id, 1); + + std::vector> resultObjects; + if (db->errorCount()) { + db->sendErrorsAsEmail(); + db->release(); + return resultObjects; + } + db->release(); + if (results.size() == 0) { + return resultObjects; + } + for (auto it = results.begin(); it != results.end(); it++) { + resultObjects.push_back(new UserBackups(new model::table::UserBackups(*it))); + } + + return resultObjects; + + } + +} \ No newline at end of file diff --git a/src/cpp/controller/UserBackups.h b/src/cpp/controller/UserBackups.h new file mode 100644 index 000000000..b55adaa9f --- /dev/null +++ b/src/cpp/controller/UserBackups.h @@ -0,0 +1,31 @@ +#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE +#define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE + +#include "../model/table/UserBackups.h" + +#include "TableControllerBase.h" + +namespace controller { + class UserBackups : public TableControllerBase + { + public: + + ~UserBackups(); + + static Poco::AutoPtr create(int user_id, const std::string& passphrase); + + static std::vector> load(int user_id); + + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } + + inline Poco::AutoPtr getModel() { return _getModel(); } + + + protected: + UserBackups(model::table::UserBackups* dbModel); + + + }; +} + +#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE \ No newline at end of file diff --git a/src/cpp/model/table/UserBackups.cpp b/src/cpp/model/table/UserBackups.cpp new file mode 100644 index 000000000..1adbfbc51 --- /dev/null +++ b/src/cpp/model/table/UserBackups.cpp @@ -0,0 +1,117 @@ +#include "UserBackups.h" + +using namespace Poco::Data::Keywords; + +namespace model { + namespace table { + + UserBackups::UserBackups() + : mUserId(0) + { + + } + + UserBackups::UserBackups(int user_id, const std::string& passphrase) + : mUserId(user_id), mPassphrase(passphrase) + { + + } + + + UserBackups::UserBackups(const UserBackupsTuple& tuple) + : ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mPassphrase(tuple.get<2>()) + { + + } + + UserBackups::~UserBackups() + { + + } + + Poco::Data::Statement UserBackups::_insertIntoDB(Poco::Data::Session session) + { + Poco::Data::Statement insert(session); + + lock(); + insert << "INSERT INTO " << getTableName() + << " (user_id, passphrase) VALUES(?,?)" + , use(mUserId), bind(mPassphrase); + unlock(); + return insert; + } + + + Poco::Data::Statement UserBackups::_loadFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, user_id, passphrase FROM " << getTableName() + << " where " << fieldName << " = ?" + , into(mID), into(mUserId), into(mPassphrase); + + + return select; + } + + Poco::Data::Statement UserBackups::_loadIdFromDB(Poco::Data::Session session) + { + Poco::Data::Statement select(session); + + select << "SELECT id FROM " << getTableName() + << " where user_id = ?" + , into(mID), use(mUserId); + + return select; + } + + Poco::Data::Statement UserBackups::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName) + { + Poco::Data::Statement select(session); + + select << "SELECT id, user_id, passphrase FROM " << getTableName() + << " where " << fieldName << " = ?"; + + + return select; + } + + Poco::Data::Statement UserBackups::_loadFromDB(Poco::Data::Session session, const std::vector& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/) + { + Poco::Data::Statement select(session); + if (fieldNames.size() <= 1) { + throw Poco::NullValueException("UserRoles::_loadFromDB fieldNames empty or contain only one field"); + } + + select << "SELECT id, user_id, passphrase FROM " << getTableName() + << " where " << fieldNames[0] << " = ? "; + if (conditionType == MYSQL_CONDITION_AND) { + for (int i = 1; i < fieldNames.size(); i++) { + select << " AND " << fieldNames[i] << " = ? "; + } + } + else if (conditionType == MYSQL_CONDITION_OR) { + for (int i = 1; i < fieldNames.size(); i++) { + select << " OR " << fieldNames[i] << " = ? "; + } + } + else { + addError(new ParamError("UserBackups::_loadFromDB", "condition type not implemented", conditionType)); + } + //<< " where " << fieldName << " = ?" + select, into(mID), into(mUserId), into(mPassphrase); + + + return select; + } + + // generic db operations + std::string UserBackups::toString() + { + std::stringstream ss; + ss << "user_id: " << mUserId << std::endl; + ss << "passphrase: " << mPassphrase << std::endl; + return ss.str(); + } + } +} \ No newline at end of file diff --git a/src/cpp/model/table/UserBackups.h b/src/cpp/model/table/UserBackups.h new file mode 100644 index 000000000..df1cc0fa0 --- /dev/null +++ b/src/cpp/model/table/UserBackups.h @@ -0,0 +1,45 @@ +#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_USER_BACKUPS_INCLUDE +#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_USER_BACKUPS_INCLUDE + +#include "ModelBase.h" + + +namespace model { + namespace table { + + typedef Poco::Tuple UserBackupsTuple; + + class UserBackups : public ModelBase + { + public: + UserBackups(int user_id, const std::string& passphrase); + UserBackups(const UserBackupsTuple& tuple); + UserBackups(); + ~UserBackups(); + + // generic db operations + const char* getTableName() const { return "user_backups"; } + std::string toString(); + + inline int getUserId() const { return mUserId; } + inline const std::string& getPassphrase() const { return mPassphrase; } + + inline void setUserId(int user_Id) { mUserId = user_Id; } + + 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& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND); + Poco::Data::Statement _insertIntoDB(Poco::Data::Session session); + + int mUserId; + std::string mPassphrase; + + }; + + } +} + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_USER_BACKUPS_INCLUDE \ No newline at end of file diff --git a/src/cpsp/adminCheckUserBackup.cpsp b/src/cpsp/adminCheckUserBackup.cpsp new file mode 100644 index 000000000..fee856df7 --- /dev/null +++ b/src/cpsp/adminCheckUserBackup.cpsp @@ -0,0 +1,98 @@ +<%@ page class="AdminCheckUserBackup" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! +#include "../crypto/KeyPair.h" +#include "../SingletonManager/ConnectionManager.h" + +#include "../controller/UserBackups.h" + +#include "Poco/Data/Binding.h" +using namespace Poco::Data::Keywords; + +typedef Poco::Tuple, std::string> UserBackupTuple; + +struct SListEntry +{ + Poco::AutoPtr user; + std::vector> backups; +}; + +%> +<%% + const char* pageName = "Admin Check User Backups"; + auto cm = ConnectionManager::getInstance(); + KeyPair keys; + std::list notMatchingEntrys; + + Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER)); + std::list userBackupEntrys; + select << "SELECT u.id, u.pubkey, b.passphrase FROM users as u LEFT JOIN user_backups as b on(u.id = b.user_id)" + , into(userBackupEntrys); + + size_t resultCount = 0; + try { + resultCount = select.execute(); + + for(auto it = userBackupEntrys.begin(); it != userBackupEntrys.end(); it++) { + auto tuple = *it; + auto pubkey = tuple.get<1>(); + if(pubkey.isNull()) { + continue; + } + auto passphrase = KeyPair::filterPassphrase(tuple.get<2>()); + auto user_id = tuple.get<0>(); + Mnemonic* wordSource = nullptr; + if(!User::validatePassphrase(passphrase, &wordSource)) { + addError(new Error("admin Check user backup", "invalid passphrase")); + addError(new ParamError("admin Check user backup", "passphrase", passphrase.data())); + addError(new ParamError("admin Check user backup", "user id", user_id)); + continue; + } else { + keys.generateFromPassphrase(passphrase.data(), wordSource); + } + if(keys.isPubkeysTheSame(pubkey.value().content().data())) { + continue; + } + SListEntry entry; + entry.user = controller::User::create(); + entry.user->load(user_id); + entry.backups = controller::UserBackups::load(user_id); + + notMatchingEntrys.push_back(entry); + + } + } + catch (Poco::Exception& ex) { + addError(new ParamError("adminCheckUserBackup", "mysql error", ex.displayText().data())); + } + + + +%><%@ include file="header_old.cpsp" %> +
+

Admin Check User Backup

+ <%= getErrorsHtml() %> +

Unmatching count: <%= notMatchingEntrys.size() %>

+
idVornameNachnameE-Mailbackups count
"; +#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( userModel->getID() ); + responseStream << ""; +#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( userModel->getFirstName() ); + responseStream << ""; +#line 91 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( userModel->getLastName() ); + responseStream << ""; +#line 92 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( userModel->getEmail() ); + responseStream << ""; +#line 93 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminCheckUserBackup.cpsp" + responseStream << ( (*it).backups.size() ); + responseStream << "
+ + + + + <% for(auto it = notMatchingEntrys.begin(); it != notMatchingEntrys.end(); it++) { + auto userModel = (*it).user->getModel(); + %> + + + + + + + + <% } %> + + +<%@ include file="footer.cpsp" %> diff --git a/src/cpsp/debugPassphrase.cpsp b/src/cpsp/debugPassphrase.cpsp index b0451f7e0..acdf059c7 100644 --- a/src/cpsp/debugPassphrase.cpsp +++ b/src/cpsp/debugPassphrase.cpsp @@ -14,6 +14,7 @@ std::string privKeyHex = ""; std::string privKeyCryptedHex = ""; User::passwordHashed pwdHashed = 0; + Poco::AutoPtr existingUser; if(!form.empty()) { auto passphrase = KeyPair::filterPassphrase(form.get("passphrase", "")); Mnemonic* wordSource = nullptr; @@ -22,7 +23,14 @@ } else { keys.generateFromPassphrase(passphrase.data(), wordSource); } - auto newUser = new User(form.get("email", "").data(), "first_name", "last_name"); + auto email = form.get("email", ""); + auto newUser = new User(email.data(), "first_name", "last_name"); + + + if(email != "") { + existingUser = controller::User::create(); + existingUser->load(email); + } newUser->validatePwd(form.get("password", ""), this); pwdHashed = newUser->getPwdHashed(); auto privKey = keys.getPrivateKey(); @@ -62,5 +70,11 @@

Private Key:
<%= privKeyHex %>

Passwort Hashed:
<%= std::to_string(pwdHashed) %>

Private key crypted:
<%= privKeyCryptedHex %>

+ <% if(!existingUser.isNull()) { + auto userModel = existingUser->getModel(); + auto dbPubkey = userModel->getPublicKey(); + %> +

user Public:
<%= KeyPair::getHex(dbPubkey, ed25519_pubkey_SIZE) %>

+ <% } %> <%@ include file="footer.cpsp" %> diff --git a/src/cpsp/login.cpsp b/src/cpsp/login.cpsp index 1fb2aca84..ea52d60b7 100644 --- a/src/cpsp/login.cpsp +++ b/src/cpsp/login.cpsp @@ -97,8 +97,15 @@ return; case USER_NO_PRIVATE_KEY: case USER_COMPLETE: + auto referer = request.find("Referer"); + std::string refererString; + if (referer != request.end()) { + refererString = referer->second; + } if(lastExternReferer != "") { response.redirect(lastExternReferer); + } else if(refererString != "") { + response.redirect(refererString); } else { response.redirect(ServerConfig::g_php_serverPath + "/"); }
idVornameNachnameE-Mailbackups count
<%= userModel->getID() %><%= userModel->getFirstName() %><%= userModel->getLastName() %><%= userModel->getEmail() %><%= (*it).backups.size() %>