mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
remove wrongly positiend submodule
This commit is contained in:
parent
c40c6b87a0
commit
a35d88c424
@ -79,6 +79,14 @@ class DashboardController extends AppController
|
||||
$stateUserQuery = $stateUserTable->find('all')->where(['public_key' => $public_key_bin]);
|
||||
if($stateUserQuery->count() == 1) {
|
||||
$stateUser = $stateUserQuery->first();
|
||||
if($stateUser->first_name != $json['user']['first_name'] ||
|
||||
$stateUser->last_name != $json['user']['last_name']) {
|
||||
$stateUser->first_name = $json['user']['first_name'];
|
||||
$stateUser->last_name = $json['user']['last_name'];
|
||||
if(!$stateUserTable->save($stateUser)) {
|
||||
$this->Flash->error(__('error updating state user ' . json_encode($stateUser->errors())));
|
||||
}
|
||||
}
|
||||
$session->write('StateUser.id', $stateUser['id']);
|
||||
//echo $stateUser['id'];
|
||||
} else {
|
||||
@ -86,7 +94,9 @@ class DashboardController extends AppController
|
||||
$newStateUser->public_key = $public_key_bin;
|
||||
$newStateUser->first_name = $json['user']['first_name'];
|
||||
$newStateUser->last_name = $json['user']['last_name'];
|
||||
$stateUserTable->save($newStateUser);
|
||||
if(!$stateUserTable->save($newStateUser)) {
|
||||
$this->Flash->error(__('error saving state user ' . json_encode($newStateUser->errors())));
|
||||
}
|
||||
$session->write('StateUser.id', $newStateUser->id);
|
||||
//echo $newStateUser->id;
|
||||
}
|
||||
|
||||
@ -33,6 +33,9 @@ class StateUser extends Entity
|
||||
'index_id' => true,
|
||||
'state_group_id' => true,
|
||||
'public_key' => true,
|
||||
'email' => true,
|
||||
'first_name' => true,
|
||||
'last_name' => true,
|
||||
'index' => true,
|
||||
'state_group' => true,
|
||||
'state_balances' => true,
|
||||
|
||||
@ -37,6 +37,7 @@ class Transaction extends Entity
|
||||
'state_group_id' => true,
|
||||
'transaction_type_id' => true,
|
||||
'tx_hash' => true,
|
||||
'memo' => true,
|
||||
'received' => true,
|
||||
'state_group' => true,
|
||||
'transaction_type' => true,
|
||||
|
||||
@ -87,8 +87,11 @@ class TransactionsTable extends Table
|
||||
->allowEmptyString('id', null, 'create');
|
||||
|
||||
$validator
|
||||
->requirePresence('tx_hash', 'create')
|
||||
->notEmptyString('tx_hash');
|
||||
//->requirePresence('tx_hash', 'create')
|
||||
->allowEmptyString('tx_hash', null, 'create');
|
||||
|
||||
$validator
|
||||
->allowEmptyString('memo', null, 'create');
|
||||
|
||||
$validator
|
||||
->dateTime('received')
|
||||
|
||||
@ -10,57 +10,115 @@ namespace Model\Transactions;
|
||||
|
||||
//use Model\Messages\Gradido\Transaction;
|
||||
//use Model\Messages\Gradido\TransactionBody;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Datasource\ConnectionManager;
|
||||
|
||||
class Transaction extends TransactionBase {
|
||||
|
||||
private $mProtoTransaction = null;
|
||||
private $mProtoTransactionBody = null;
|
||||
private $errors = [];
|
||||
private $mTransactionBody = null;
|
||||
|
||||
public function __construct($base64Data) {
|
||||
$transactionBin = base64_decode($base64Data);
|
||||
if($transactionBin == FALSE) {
|
||||
//$this->addError('base64 decode failed');
|
||||
$this->addError(['data' => $base64Data, 'bin' => $transactionBin, 'msg' => 'base64 decode error']);
|
||||
$this->addError('Transaction', ['data' => $base64Data, 'bin' => $transactionBin, 'msg' => 'base64 decode error']);
|
||||
} else {
|
||||
$this->mProtoTransaction = new \Model\Messages\Gradido\Transaction();
|
||||
$this->mProtoTransaction->mergeFromString($transactionBin);
|
||||
//echo 'serialize to json: <br>';
|
||||
//echo $this->mProtoTransaction->serializeToJsonString();
|
||||
|
||||
$this->mProtoTransactionBody = new \Model\Messages\Gradido\TransactionBody();
|
||||
$this->mProtoTransactionBody->mergeFromString($this->mProtoTransaction->getBodyBytes());
|
||||
|
||||
$data = $this->mProtoTransactionBody->getData();
|
||||
var_dump($data);
|
||||
$this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTransactionBody() {
|
||||
return $this->mTransactionBody;
|
||||
}
|
||||
|
||||
public function getFirstPublic() {
|
||||
$sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
|
||||
return $sigPairs[0]->getPubKey();
|
||||
}
|
||||
|
||||
public function validate() {
|
||||
$sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
|
||||
$bodyBytes = $this->mProtoTransaction->getBodyBytes();
|
||||
|
||||
|
||||
if(!$sigPairs || count($sigPairs) < 1) {
|
||||
$this->addError('Transaction::validate', 'no signature found');
|
||||
return false;
|
||||
}
|
||||
|
||||
// check signature(s)
|
||||
foreach($sigPairs as $sigPair) {
|
||||
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
|
||||
$pubkey = $sigPair->getPubKey();
|
||||
$signature = $sigPair->getEd25519();
|
||||
if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
|
||||
$this->addError('signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
|
||||
$this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->mTransactionBody->validate($sigPairs)) {
|
||||
$this->addErrors($this->mTransactionBody->getErrors());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getErrors() {
|
||||
return $this->errors;
|
||||
public function save()
|
||||
{
|
||||
$connection = ConnectionManager::get('default');
|
||||
$connection->begin();
|
||||
//id transaction_id signature pubkey
|
||||
|
||||
if (!$this->mTransactionBody->save($this->getFirstPublic())) {
|
||||
$this->addErrors($this->mTransactionBody->getErrors());
|
||||
$connection->rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
// save transaction signatures
|
||||
$transactionsSignaturesTable = TableRegistry::getTableLocator()->get('transaction_signatures');
|
||||
$transactionId = $this->mTransactionBody->getTransactionID();
|
||||
//signature pubkey
|
||||
|
||||
$sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
|
||||
echo "sigPairs: "; var_dump($sigPairs);
|
||||
$signatureEntitys = [];
|
||||
foreach($sigPairs as $sigPair) {
|
||||
$signatureEntity = $transactionsSignaturesTable->newEntity();
|
||||
|
||||
$signatureEntity->transaction_id = $transactionId;
|
||||
$signatureEntity->signature = $sigPair->getEd25519();
|
||||
$signatureEntity->pubkey = $sigPair->getPubKey();
|
||||
array_push($signatureEntitys, $signatureEntity);
|
||||
}
|
||||
//debug($signatureEntitys);
|
||||
if(!$transactionsSignaturesTable->saveMany($signatureEntitys)) {
|
||||
foreach($signatureEntitys as $entity) {
|
||||
$errors = $entity->getErrors();
|
||||
if(!$errors && count($errors) > 0) {
|
||||
$pubkeyHex = bin2hex($entity->pubkey);
|
||||
$this->addError('Transaction::save', 'error saving signature for pubkey: ' . $pubkeyHex . ', with errors: ' . json_encode($errors) );
|
||||
}
|
||||
}
|
||||
$connection->rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
$connection->commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function hasErrors() {
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
|
||||
private function addError($message) {
|
||||
array_push($this->errors, $message);
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,6 +2,42 @@
|
||||
|
||||
namespace Model\Transactions;
|
||||
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
class TransactionBase {
|
||||
private $errors = [];
|
||||
|
||||
public function getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public function addError($functionName, $errorName) {
|
||||
array_push($this->errors, [$functionName => $errorName]);
|
||||
}
|
||||
|
||||
public function addErrors($errors) {
|
||||
$this->errors = array_merge($this->errors, $errors);
|
||||
}
|
||||
|
||||
public function hasErrors() {
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
protected function getStateUserId($publicKey) {
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
|
||||
$stateUser = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $publicKey])->first();
|
||||
if($stateUser) {
|
||||
return $stateUser->id;
|
||||
}
|
||||
// create new entry
|
||||
$stateUserEntity = $stateUsersTable->newEntity();
|
||||
$stateUserEntity->public_key = $publicKey;
|
||||
if($stateUsersTable->save($stateUserEntity)) {
|
||||
return $stateUserEntity->id;
|
||||
} else {
|
||||
$this->addError('TransactionBase::getStateUserId', 'error saving new state user with error: ' . json_encode($stateUserEntity->getErrors()));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,76 @@
|
||||
|
||||
namespace Model\Transactions;
|
||||
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
class TransactionBody extends TransactionBase {
|
||||
private $mProtoTransactionBody = null;
|
||||
private $mSpecificTransaction = null;
|
||||
private $mTransactionID = 0;
|
||||
|
||||
public function __construct($bodyBytes) {
|
||||
$this->mProtoTransactionBody = new \Model\Messages\Gradido\TransactionBody();
|
||||
$this->mProtoTransactionBody->mergeFromString($bodyBytes);
|
||||
switch($this->mProtoTransactionBody->getData()) {
|
||||
case 'creation' : $this->mSpecificTransaction = new TransactionCreation($this->mProtoTransactionBody->getCreation()); break;
|
||||
case 'transfer' : $this->mSpecificTransaction = new TransactionTransfer($this->mProtoTransactionBody->getTransfer()); break;
|
||||
}
|
||||
}
|
||||
|
||||
public function validate($sigPairs) {
|
||||
if(!$this->mSpecificTransaction->validate($sigPairs)) {
|
||||
$this->addErrors($this->mSpecificTransaction->getErrors());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSpecificTransaction() {
|
||||
return $this->mSpecificTransaction;
|
||||
}
|
||||
|
||||
public function getMemo() {
|
||||
return $this->mProtoTransactionBody->getMemo();
|
||||
}
|
||||
|
||||
public function getTransactionTypeName()
|
||||
{
|
||||
return $this->mProtoTransactionBody->getData();
|
||||
}
|
||||
|
||||
public function save($firstPublic) {
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('transactions');
|
||||
$transactionEntity = $transactionsTable->newEntity();
|
||||
|
||||
// transaction type id
|
||||
$transactionTypesTable = TableRegistry::getTableLocator()->get('transaction_types');
|
||||
|
||||
$typeName = $this->getTransactionTypeName();
|
||||
$transactionType = $transactionTypesTable->find('all')->where(['name' => $typeName])->select(['id'])->first();
|
||||
if($transactionType == NULL) {
|
||||
$this->addError('TransactionBody::save', 'zero type id for type: ' . $typeName);
|
||||
return false;
|
||||
}
|
||||
$transactionEntity->transaction_type_id = $transactionType->id;
|
||||
$transactionEntity->memo = $this->getMemo();
|
||||
|
||||
if ($transactionsTable->save($transactionEntity)) {
|
||||
// success
|
||||
$this->mTransactionID = $transactionEntity->id;
|
||||
if(!$this->mSpecificTransaction->save($transactionEntity->id, $firstPublic)) {
|
||||
$this->addErrors($this->mSpecificTransaction->getErrors());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->addError('TransactionBody::save', 'error saving transaction with: ' . json_encode($transactionEntity->getError()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTransactionID() {
|
||||
return $this->mTransactionID;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,76 @@ namespace Model\Transactions;
|
||||
|
||||
//use App\Model\Transactions\TransactionBase;
|
||||
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
class TransactionCreation extends TransactionBase {
|
||||
|
||||
private $protoTransactionCreation;
|
||||
private $transactionCreationsTable;
|
||||
|
||||
public function __construct($protoTransactionCreation) {
|
||||
$this->protoTransactionCreation = $protoTransactionCreation;
|
||||
$this->transactionCreationsTable = TableRegistry::getTableLocator()->get('transaction_creations');
|
||||
}
|
||||
|
||||
public function getAmount() {
|
||||
return $this->protoTransactionCreation->getReceiverAmount()->getAmount();
|
||||
}
|
||||
|
||||
public function getReceiverPublic() {
|
||||
return $this->protoTransactionCreation->getReceiverAmount()->getEd25519ReceiverPubkey();
|
||||
}
|
||||
|
||||
public function getIdentHash() {
|
||||
return $this->protoTransactionCreation->getIdentHash();
|
||||
}
|
||||
|
||||
public function validate($sigPairs) {
|
||||
// check if receiver public is not in signature list
|
||||
$receiverPublic = $this->getReceiverPublic();
|
||||
foreach($sigPairs as $sigPair) {
|
||||
$pubkey = $sigPair->getPubKey();
|
||||
if($pubkey == $receiverPublic) {
|
||||
$this->addError('TransactionCreation::validate', 'receiver aren\'t allowed to sign creation Transaction');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if creation threshold for this month isn't reached
|
||||
$existingCreations = $this->transactionCreationsTable
|
||||
->find('all')
|
||||
->group('ident_hash')
|
||||
->where(['ident_hash' => $this->getIdentHash()]);
|
||||
$existingCreations->select(['amount_sum' => $existingCreations->func()->sum('amount')]);
|
||||
debug($existingCreations);
|
||||
if($existingCreations->count() > 0) {
|
||||
var_dump($existingCreations->toArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save($transaction_id, $firstPublic) {
|
||||
|
||||
$transactionCreationEntity = $this->transactionCreationsTable->newEntity();
|
||||
|
||||
$transactionCreationEntity->transaction_id = $transaction_id;
|
||||
|
||||
// state user id
|
||||
$state_user_id = $this->getStateUserId($firstPublic);
|
||||
if(!$state_user_id) {
|
||||
$this->addError('TransactionCreation::save', 'couldn\'t get state user id');
|
||||
return false;
|
||||
}
|
||||
$transactionCreationEntity->state_user_id = $state_user_id;
|
||||
$transactionCreationEntity->amount = $this->getAmount();
|
||||
$transactionCreationEntity->ident_hash = $this->getIdentHash();
|
||||
|
||||
if(!$this->transactionCreationsTable->save($transactionCreationEntity)) {
|
||||
$this->addError('TransactionCreation::save', 'error saving transactionCreation with errors: ' . json_encode($transactionCreationEntity->getErrors()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,6 +5,18 @@ namespace Model\Transactions;
|
||||
//use App\Model\Transactions\TransactionBase;
|
||||
|
||||
class TransactionTransfer extends TransactionBase {
|
||||
|
||||
private $protoTransactionTransfer;
|
||||
|
||||
public function __construct($protoTransactionTransfer) {
|
||||
$this->protoTransactionTransfer = $protoTransactionTransfer;
|
||||
}
|
||||
|
||||
public function validate($sigPairs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save($transaction_id, $firstPublic) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ $transactionPendings = $session->read('Transactions.pending');
|
||||
<body>
|
||||
<div class="versionstring dev-info">
|
||||
<p class="grd_small">Community Server in Entwicklung</p>
|
||||
<p class="grd_small">Alpha 0.4.4</p>
|
||||
<p class="grd_small">Alpha 0.5.0</p>
|
||||
</div>
|
||||
<nav class="grd-left-bar expanded" data-topbar role="navigation">
|
||||
<div class="grd-left-bar-section">
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
message Key {
|
||||
oneof key {
|
||||
bytes ed25519 = 2; // ed25519 signature (libsodium default)
|
||||
bytes ed25519_ref10 = 3; // ed25519 ref10 signature
|
||||
}
|
||||
}
|
||||
|
||||
message SignaturePair {
|
||||
bytes pubKey = 1;
|
||||
oneof signature {
|
||||
bytes ed25519 = 2; // ed25519 signature (libsodium default)
|
||||
bytes ed25519_ref10 = 3; // ed25519 ref10 signature
|
||||
}
|
||||
}
|
||||
|
||||
message SignatureMap {
|
||||
repeated SignaturePair sigPair = 1; // Each signature pair corresponds to a unique Key required to sign the transaction.
|
||||
}
|
||||
|
||||
/* An exact date and time. This is the same data structure as the protobuf Timestamp.proto (see the comments in https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto) */
|
||||
message Timestamp {
|
||||
int64 seconds = 1; // Number of complete seconds since the start of the epoch
|
||||
int32 nanos = 2; // Number of nanoseconds since the start of the last second
|
||||
}
|
||||
|
||||
/* An exact date and time, with a resolution of one second (no nanoseconds). */
|
||||
message TimestampSeconds {
|
||||
int64 seconds = 1; // Number of complete seconds since the start of the epoch
|
||||
}
|
||||
|
||||
message SenderAmount {
|
||||
bytes ed25519_sender_pubkey = 1;
|
||||
sint64 amount = 2;
|
||||
sint64 senderFinalBalance = 3; // sender balance after transaction, including perishability
|
||||
}
|
||||
|
||||
message ReceiverAmount {
|
||||
bytes ed25519_receiver_pubkey = 1;
|
||||
sint64 amount = 2;
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
import "BasicTypes.proto";
|
||||
|
||||
// need signature from this group and from parent (if it isn't zero)
|
||||
message StateCreateGroup {
|
||||
string name = 1;
|
||||
Key groupPublicKey = 2;
|
||||
Key parentGroupPublicKey = 3;
|
||||
reserved "hederaConsensusId";
|
||||
reserved 4;
|
||||
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
import "BasicTypes.proto";
|
||||
|
||||
// need signature from this group and from both parents (if it isn't zero)
|
||||
message StateGroupChangeParent {
|
||||
Key groupPublicKey = 1;
|
||||
Key newParentGroupPublicKey = 2;
|
||||
Key oldParentGroupPublicKey = 3;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
import "BasicTypes.proto";
|
||||
|
||||
/*
|
||||
id will be set by Node server
|
||||
txHash will be also set by Node server,
|
||||
calculated from previous transaction txHash and this id, sigMap and received;
|
||||
*/
|
||||
|
||||
message Transaction {
|
||||
uint64 id = 1;
|
||||
TimestampSeconds received = 2;
|
||||
SignatureMap sigMap = 3;
|
||||
bytes txHash = 4;
|
||||
bytes bodyBytes = 5;
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
import "Transfer.proto";
|
||||
import "StateCreateGroup.proto";
|
||||
import "StateGroupChangeParent.proto";
|
||||
import "TransactionCreation.proto";
|
||||
|
||||
message TransactionBody {
|
||||
string memo = 1; // max 150 chars
|
||||
oneof data {
|
||||
StateCreateGroup createGroup = 2;
|
||||
StateGroupChangeParent groupChangeParent = 3;
|
||||
Transfer transfer = 4;
|
||||
TransactionCreation creation = 5;
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
import "BasicTypes.proto";
|
||||
|
||||
// need signature from group admin or
|
||||
// percent of group users another than the receiver
|
||||
message TransactionCreation {
|
||||
ReceiverAmount receiverAmount = 1;
|
||||
sint32 ident_hash = 2;
|
||||
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package model.messages.gradido;
|
||||
|
||||
import "BasicTypes.proto";
|
||||
|
||||
message Transfer {
|
||||
repeated SenderAmount senderAmounts = 1;
|
||||
repeated ReceiverAmount receiverAmounts = 2;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user