Merge pull request #523 from gradido/login_prevent_double_spent

compare with last transaction sended
This commit is contained in:
einhornimmond 2021-06-14 15:03:17 +02:00 committed by GitHub
commit fe74efd283
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 0 deletions

View File

@ -140,6 +140,13 @@ Poco::JSON::Object* JsonCreateTransaction::transfer(Poco::Dynamic::Var params)
try {
auto transaction = model::gradido::Transaction::createTransfer(sender_user, target_pubkey, mTargetGroup, amount, mMemo, mBlockchainType);
if (mSession->lastTransactionTheSame(transaction)) {
return stateError("transaction are the same as the last (within 100 seconds)");
}
else {
mSession->setLastTransaction(transaction);
}
if (mAutoSign) {
Poco::JSON::Array errors;
transaction->sign(sender_user);

View File

@ -919,6 +919,17 @@ bool Session::useOrGeneratePassphrase(const std::string& passphase)
}
*/
bool Session::lastTransactionTheSame(Poco::AutoPtr<model::gradido::Transaction> newTransaction)
{
assert(!newTransaction.isNull());
lock();
if (mLastTransaction.isNull()) {
return false;
}
bool result = mLastTransaction->isTheSameTransaction(newTransaction);
unlock();
return result;
}
bool Session::generateKeys(bool savePrivkey, bool savePassphrase)
{

View File

@ -19,6 +19,8 @@
#include "../controller/EmailVerificationCode.h"
#include "model/gradido/Transaction.h"
#include "Poco/Thread.h"
#include "Poco/Types.h"
#include "Poco/DateTime.h"
@ -163,6 +165,8 @@ public:
// ------------------------ transactions functions ----------------------------
inline void setLastTransaction(Poco::AutoPtr<model::gradido::Transaction> lastTransaction) { lock(); mLastTransaction = lastTransaction; unlock(); }
bool lastTransactionTheSame(Poco::AutoPtr<model::gradido::Transaction> newTransaction);
inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; }
void setLanguage(Languages lang);
@ -188,6 +192,7 @@ protected:
private:
int mHandleId;
Poco::AutoPtr<controller::User> mNewUser;
std::string mPassphrase;
@ -200,6 +205,7 @@ private:
Poco::AutoPtr<controller::EmailVerificationCode> mEmailVerificationCodeObject;
std::shared_mutex mSharedMutex;
Poco::AutoPtr<model::gradido::Transaction> mLastTransaction;
SessionStates mState;

View File

@ -630,6 +630,31 @@ namespace model {
}
bool Transaction::isTheSameTransaction(Poco::AutoPtr<Transaction> other)
{
bool result = false;
auto other_proto = other->getTransactionBody()->getBody();
auto other_created = other_proto->created();
auto own_body_bytes = getTransactionBody()->getBodyBytes();
auto own_body_updated = new proto::gradido::TransactionBody;
own_body_updated->ParseFromString(own_body_bytes);
auto own_created = own_body_updated->mutable_created();
Poco::Int64 timeDiff = other_created.seconds() - own_created->seconds();
*own_created = other_created;
result = own_body_updated->SerializeAsString() == other_proto->SerializeAsString();
delete own_body_updated;
// if they are more than 10 seconds between transaction they consider as not the same
if (abs(timeDiff) > 10) {
return false;
}
return result;
}
/// TASK ////////////////////////
SendTransactionTask::SendTransactionTask(Poco::AutoPtr<Transaction> transaction)

View File

@ -86,6 +86,8 @@ namespace model {
std::string getTransactionAsJson(bool replaceBase64WithHex = false);
inline Poco::AutoPtr<Transaction> getPairedTransaction() { return mPairedTransaction; }
bool isTheSameTransaction(Poco::AutoPtr<Transaction> other);
protected: