work on check transaction

This commit is contained in:
Dario 2019-10-26 19:19:52 +02:00
parent afdee88dec
commit cd6dcacda3
14 changed files with 174 additions and 30 deletions

View File

@ -14,6 +14,7 @@
#include "ElopageWebhook.h" #include "ElopageWebhook.h"
#include "UpdateUserPasswordPage.h" #include "UpdateUserPasswordPage.h"
#include "Error500Page.h" #include "Error500Page.h"
#include "CheckTransactionPage.h"
#include "../SingletonManager/SessionManager.h" #include "../SingletonManager/SessionManager.h"
@ -113,7 +114,10 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
//else if (uri == "/saveKeys") { //else if (uri == "/saveKeys") {
return new SaveKeysPage(s); return new SaveKeysPage(s);
} }
if (s && !s->getUser().isNull()) { if (url_first_part == "/checkTransactions") {
return new CheckTransactionPage(s);
}
if (s && !user.isNull() && user->hasCryptoKey()) {
//printf("[PageRequestHandlerFactory] go to dashboard page with user\n"); //printf("[PageRequestHandlerFactory] go to dashboard page with user\n");
return new DashboardPage(s); return new DashboardPage(s);
} }

View File

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

View File

@ -0,0 +1,50 @@
#include "JsonTransaction.h"
#include "Poco/URI.h"
#include "../SingletonManager/SessionManager.h"
Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params)
{
Poco::JSON::Object* result = new Poco::JSON::Object;
int session_id = 0;
if (params.isVector()) {
const Poco::URI::QueryParameters queryParams = params.extract<Poco::URI::QueryParameters>();
auto transactionIT = queryParams.begin();
for (auto it = queryParams.begin(); it != queryParams.end(); it++) {
if (it->first == "session_id") {
session_id = stoi(it->second);
//break;
}
else if (it->first == "transaction_base64") {
transactionIT = it;
}
}
if (session_id) {
auto sm = SessionManager::getInstance();
auto session = sm->getSession(session_id);
if (!session) {
result->set("state", "error");
result->set("msg", "session not found");
return result;
}
if (!session->startProcessingTransaction(transactionIT->second)) {
result->set("state", "error");
result->set("msg", "already enlisted");
return result;
}
result->set("state", "success");
return result;
}
else {
result->set("state", "error");
result->set("msg", "session id not set");
return result;
}
}
result->set("state", "error");
result->set("msg", "format not implemented");
return result;
}

View File

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

View File

@ -79,7 +79,7 @@ int WritePassphraseIntoDB::run()
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
Session::Session(int handle) Session::Session(int handle)
: mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mState(SESSION_STATE_EMPTY), mActive(false), mProcessingTransaction(nullptr) : mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mState(SESSION_STATE_EMPTY), mActive(false)
{ {
} }
@ -98,7 +98,6 @@ void Session::reset()
lock(); lock();
mSessionUser = nullptr; mSessionUser = nullptr;
mProcessingTransaction = nullptr;
// watch out // watch out
//updateTimeout(); //updateTimeout();
@ -279,7 +278,7 @@ bool Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
return false; return false;
} }
bool Session::startProcessingTransaction(std::string proto_message_base64) bool Session::startProcessingTransaction(const std::string& proto_message_base64)
{ {
lock(); lock();
HASH hs = ProcessingTransaction::calculateHash(proto_message_base64); HASH hs = ProcessingTransaction::calculateHash(proto_message_base64);
@ -294,7 +293,7 @@ bool Session::startProcessingTransaction(std::string proto_message_base64)
return false; return false;
} }
} }
UniLib::controller::TaskPtr processorTask(new ProcessingTransaction(proto_message_base64)); Poco::AutoPtr<ProcessingTransaction> processorTask(new ProcessingTransaction(proto_message_base64));
processorTask->scheduleTask(processorTask); processorTask->scheduleTask(processorTask);
mProcessingTransactions.push_back(processorTask); mProcessingTransactions.push_back(processorTask);
unlock(); unlock();
@ -302,14 +301,31 @@ bool Session::startProcessingTransaction(std::string proto_message_base64)
} }
Poco::AutoPtr<ProcessingTransaction> Session::getNextReadyTransaction() Poco::AutoPtr<ProcessingTransaction> Session::getNextReadyTransaction(size_t* working/* = nullptr*/)
{ {
lock(); lock();
if (working) {
*working = 0;
}
Poco::AutoPtr<ProcessingTransaction> ret;
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) { for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
if ((*it)->isTaskFinished()) { if (working && !(*it)->isTaskFinished()) {
*working++;
}
if (ret.isNull() && (*it)->isTaskFinished()) {
if (!working) {
unlock();
return *it;
}
// no early exit
else {
ret = *it;
}
} }
} }
unlock();
return nullptr;
} }
bool Session::isPwdValid(const std::string& pwd) bool Session::isPwdValid(const std::string& pwd)
@ -324,13 +340,21 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo
{ {
//Profiler usedTime; //Profiler usedTime;
lock(); lock();
if (mSessionUser) mSessionUser = nullptr; if (mSessionUser && mSessionUser->getEmail() != email) {
mSessionUser = new User(email.data()); mSessionUser = nullptr;
}
if (!mSessionUser) {
// load user for email only once from db
mSessionUser = new User(email.data());
}
if (mSessionUser->getUserState() >= USER_LOADED_FROM_DB) { if (mSessionUser->getUserState() >= USER_LOADED_FROM_DB) {
if (!mSessionUser->validatePwd(password, this)) { if (!mSessionUser->validatePwd(password, this)) {
return USER_PASSWORD_INCORRECT; return USER_PASSWORD_INCORRECT;
} }
} }
else {
User::fakeCreateCryptoKey();
}
/*if (!mSessionUser->validatePwd(password, this)) { /*if (!mSessionUser->validatePwd(password, this)) {
addError(new Error("Login", "E-Mail oder Passwort nicht korrekt, bitte versuche es erneut!")); addError(new Error("Login", "E-Mail oder Passwort nicht korrekt, bitte versuche es erneut!"));

View File

@ -65,7 +65,7 @@ public:
bool updateEmailVerification(Poco::UInt64 emailVerificationCode); bool updateEmailVerification(Poco::UInt64 emailVerificationCode);
bool startProcessingTransaction(std::string proto_message_base64);
Poco::Net::HTTPCookie getLoginCookie(); Poco::Net::HTTPCookie getLoginCookie();
@ -98,7 +98,11 @@ public:
inline Poco::DateTime getLastActivity() { return mLastActivity; } inline Poco::DateTime getLastActivity() { return mLastActivity; }
Poco::AutoPtr<ProcessingTransaction> getNextReadyTransaction(); //! \return true if succeed
bool startProcessingTransaction(const std::string& proto_message_base64);
//! \param working if set will filled with transaction running
Poco::AutoPtr<ProcessingTransaction> getNextReadyTransaction(size_t* working = nullptr);
inline size_t getProcessingTransactionCount() { lock(); auto ret = mProcessingTransactions.size(); unlock(); return ret; }
protected: protected:
void updateTimeout(); void updateTimeout();
@ -123,7 +127,6 @@ private:
bool mActive; bool mActive;
std::list<Poco::AutoPtr<ProcessingTransaction>> mProcessingTransactions; std::list<Poco::AutoPtr<ProcessingTransaction>> mProcessingTransactions;
std::list<Poco::AutoPtr<ProcessingTransaction>>
}; };

View File

@ -32,7 +32,7 @@ int TransactionCreation::prepare()
mReceiverUser = new User(receiverPublic.data()); mReceiverUser = new User(receiverPublic.data());
getErrors(mReceiverUser); getErrors(mReceiverUser);
if (mReceiverUser->getUserState() == USER_EMPTY) { if (mReceiverUser->getUserState() == USER_EMPTY) {
sodium_bin2hex(mReceiverPublicHex, 64, (const unsigned char*)receiverPublic.data(), receiverPublic.size()); sodium_bin2hex(mReceiverPublicHex, 65, (const unsigned char*)receiverPublic.data(), receiverPublic.size());
delete mReceiverUser; delete mReceiverUser;
mReceiverUser = nullptr; mReceiverUser = nullptr;
} }

View File

@ -553,12 +553,12 @@ bool User::deleteFromDB()
void User::duplicate() void User::duplicate()
{ {
mWorkingMutex.lock(); mReferenceMutex.lock();
mReferenceCount++; mReferenceCount++;
#ifdef DEBUG_USER_DELETE_ENV #ifdef DEBUG_USER_DELETE_ENV
printf("[User::duplicate] new value: %d\n", mReferenceCount); printf("[User::duplicate] new value: %d\n", mReferenceCount);
#endif #endif
mWorkingMutex.unlock(); mReferenceMutex.unlock();
} }
void User::release() void User::release()
@ -566,17 +566,17 @@ void User::release()
if (!mCreateCryptoKeyTask.isNull() && mCreateCryptoKeyTask->isTaskFinished()) { if (!mCreateCryptoKeyTask.isNull() && mCreateCryptoKeyTask->isTaskFinished()) {
mCreateCryptoKeyTask = nullptr; mCreateCryptoKeyTask = nullptr;
} }
mWorkingMutex.lock(); mReferenceMutex.lock();
mReferenceCount--; mReferenceCount--;
#ifdef DEBUG_USER_DELETE_ENV #ifdef DEBUG_USER_DELETE_ENV
printf("[User::release] new value: %d, this: %d\n", mReferenceCount, this); printf("[User::release] new value: %d, this: %d\n", mReferenceCount, this);
#endif #endif
if (0 == mReferenceCount) { if (0 == mReferenceCount) {
mWorkingMutex.unlock(); mReferenceMutex.unlock();
delete this; delete this;
return; return;
} }
mWorkingMutex.unlock(); mReferenceMutex.unlock();
} }
@ -624,6 +624,11 @@ ObfusArray* User::createCryptoKey(const std::string& password)
return cryptoKey; return cryptoKey;
} }
void User::fakeCreateCryptoKey()
{
Poco::Thread::sleep(820);
}
bool User::generateKeys(bool savePrivkey, const std::string& passphrase, Session* session) bool User::generateKeys(bool savePrivkey, const std::string& passphrase, Session* session)
{ {
Profiler timeUsed; Profiler timeUsed;

View File

@ -94,13 +94,16 @@ public:
// for poco auto ptr // for poco auto ptr
void duplicate(); void duplicate();
void release(); void release();
//! \brief wait time create crypto key is normally running
static void fakeCreateCryptoKey();
protected: protected:
typedef Poco::UInt64 passwordHashed; typedef Poco::UInt64 passwordHashed;
ObfusArray* createCryptoKey(const std::string& password); ObfusArray* createCryptoKey(const std::string& password);
inline void setCryptoKey(ObfusArray* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); } inline void setCryptoKey(ObfusArray* cryptoKey) { lock(); mCryptoKey = cryptoKey; unlock(); }
void detectState(); //void detectState();
Poco::Data::Statement insertIntoDB(Poco::Data::Session session); Poco::Data::Statement insertIntoDB(Poco::Data::Session session);
bool updateIntoDB(UserFields fieldType); bool updateIntoDB(UserFields fieldType);
@ -135,6 +138,7 @@ private:
ObfusArray* mCryptoKey; ObfusArray* mCryptoKey;
Poco::Mutex mWorkingMutex; Poco::Mutex mWorkingMutex;
Poco::Mutex mReferenceMutex;
// for poco auto ptr // for poco auto ptr
int mReferenceCount; int mReferenceCount;

View File

@ -4,7 +4,7 @@
#include "../model/TransactionCreation.h" #include "../model/TransactionCreation.h"
#include "../model/TransactionTransfer.h" #include "../model/TransactionTransfer.h"
ProcessingTransaction::ProcessingTransaction(std::string proto_message_base64) ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64)
: mType(TRANSACTION_NONE), mProtoMessageBase64(proto_message_base64), mTransactionSpecific(nullptr) : mType(TRANSACTION_NONE), mProtoMessageBase64(proto_message_base64), mTransactionSpecific(nullptr)
{ {
mHashMutex.lock(); mHashMutex.lock();
@ -23,14 +23,13 @@ ProcessingTransaction::~ProcessingTransaction()
} }
HASH ProcessingTransaction::calculateHash(std::string proto_message_base64) HASH ProcessingTransaction::calculateHash(const std::string& proto_message_base64)
{ {
return DRMakeStringHash(proto_message_base64.data(), proto_message_base64.size()); return DRMakeStringHash(proto_message_base64.data(), proto_message_base64.size());
} }
int ProcessingTransaction::run() int ProcessingTransaction::run()
{ {
lock(); lock();
//mTransactionBody.ParseFromString(); //mTransactionBody.ParseFromString();
unsigned char* binBuffer = (unsigned char*)malloc(mProtoMessageBase64.size()); unsigned char* binBuffer = (unsigned char*)malloc(mProtoMessageBase64.size());

View File

@ -4,6 +4,7 @@
#include "CPUTask.h" #include "CPUTask.h"
#include "../model/ErrorList.h" #include "../model/ErrorList.h"
#include "../Crypto/DRHash.h"
#include "../model/TransactionBase.h" #include "../model/TransactionBase.h"
#include "../proto/gradido/TransactionBody.pb.h" #include "../proto/gradido/TransactionBody.pb.h"
@ -27,7 +28,7 @@ class TransactionTransfer;
class ProcessingTransaction : public UniLib::controller::CPUTask, public ErrorList class ProcessingTransaction : public UniLib::controller::CPUTask, public ErrorList
{ {
public: public:
ProcessingTransaction(std::string proto_message_base64); ProcessingTransaction(const std::string& proto_message_base64);
virtual ~ProcessingTransaction(); virtual ~ProcessingTransaction();
int run(); int run();
@ -44,7 +45,7 @@ public:
TransactionCreation* getCreationTransaction(); TransactionCreation* getCreationTransaction();
TransactionTransfer* getTransferTransaction(); TransactionTransfer* getTransferTransaction();
static HASH calculateHash(std::string proto_message_base64); static HASH calculateHash(const std::string& proto_message_base64);
inline HASH getHash() { mHashMutex.lock(); HASH hs = mHash; mHashMutex.unlock(); return hs; } inline HASH getHash() { mHashMutex.lock(); HASH hs = mHash; mHashMutex.unlock(); return hs; }
protected: protected:

View File

@ -59,23 +59,23 @@ namespace UniLib {
void Task::duplicate() void Task::duplicate()
{ {
lock(); mReferenceMutex.lock();
mReferenceCount++; mReferenceCount++;
//printf("[Task::duplicate] new value: %d\n", mReferenceCount); //printf("[Task::duplicate] new value: %d\n", mReferenceCount);
unlock(); mReferenceMutex.unlock();
} }
void Task::release() void Task::release()
{ {
lock(); mReferenceMutex.lock();
mReferenceCount--; mReferenceCount--;
//printf("[Task::release] new value: %d\n", mReferenceCount); //printf("[Task::release] new value: %d\n", mReferenceCount);
if (0 == mReferenceCount) { if (0 == mReferenceCount) {
unlock(); mReferenceMutex.unlock();
delete this; delete this;
return; return;
} }
unlock(); mReferenceMutex.unlock();
} }

View File

@ -119,6 +119,7 @@ namespace UniLib {
TaskPtr* mParentTaskPtrArray; TaskPtr* mParentTaskPtrArray;
size_t mParentTaskPtrArraySize; size_t mParentTaskPtrArraySize;
Poco::Mutex mWorkingMutex; Poco::Mutex mWorkingMutex;
Poco::Mutex mReferenceMutex;
bool mDeleted; bool mDeleted;
bool mFinished; bool mFinished;
// for poco auto ptr // for poco auto ptr

View File

@ -6,8 +6,28 @@
<%@ page compressed="true" %> <%@ page compressed="true" %>
<%! <%!
#include "../SingletonManager/SessionManager.h" #include "../SingletonManager/SessionManager.h"
enum PageState {
PAGE_TRANSACTION_CREATION,
PAGE_TRANSACTION_TRANSFER,
PAGE_NO_TRANSACTIONS
};
%> %>
<%% <%%
PageState state = PAGE_NO_TRANSACTIONS;
size_t notReadyTransactions = 0;
size_t sumTransactions = mSession->getProcessingTransactionCount();
auto processingTransaction = mSession->getNextReadyTransaction(&notReadyTransactions);
if(!processingTransaction.isNull()) {
auto transactionType = processingTransaction->getType();
switch(transactionType) {
case TRANSACTION_CREATION: state = PAGE_TRANSACTION_CREATION; break;
case TRANSACTION_TRANSFER: state = PAGE_TRANSACTION_TRANSFER; break;
}
}
%> %>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -39,7 +59,20 @@ label:not(.grd_radio_label) {
<h1>Eine Transaktion pr&uuml;fen</h1> <h1>Eine Transaktion pr&uuml;fen</h1>
<%= getErrorsHtml() %> <%= getErrorsHtml() %>
<% if(sumTransactions - notReadyTransactions != 1) { %>
<pre><%= sumTransactions - notReadyTransactions %> von <%= sumTransactions %> Transaktionen sind bereit zum pr&uuml;fen</pre>
<% } %>
<% if(state == PAGE_NO_TRANSACTIONS) { %>
<div class="grd_text-max-width">
<% if(sumTransactions == 0) { %>
<div class="grd_text">Es gibt zurzeit keine Transaktionen zum &uuml;berpr&uuml;fen</div>
<% } else { %>
<div class="grd_text">Transaktion(en) werden noch vorbereitet, bitte lade die Seite in wenigen Augenblicken erneut.</div>
<% } %>
</div>
<% } else if(state == PAGE_TRANSACTION_CREATION) { %>
<% } %>
</div> </div>
<div class="grd-time-used"> <div class="grd-time-used">
<%= mTimeProfiler.string() %> <%= mTimeProfiler.string() %>