update gradido kuerzel

This commit is contained in:
Dario Rekowski on RockPI 2019-12-03 09:42:18 +00:00
parent 2475b6b7ad
commit 0bd1771ecf
11 changed files with 189 additions and 130 deletions

View File

@ -15,7 +15,7 @@ class ServerUsersController extends AppController
public function initialize()
{
parent::initialize();
//$this->Auth->allow(['add', 'edit']);
$this->Auth->allow(['add', 'edit']);
$this->Auth->deny('index');
}

View File

@ -3,6 +3,8 @@ namespace App\Controller;
use App\Controller\AppController;
use Model\Transactions\TransactionCreation;
/**
* StateUsers Controller
*
@ -26,6 +28,15 @@ class StateUsersController extends AppController
$this->set(compact('stateUsers'));
}
public function listIdentHashes()
{
$stateUsers = $this->StateUsers->find('all')->toArray();
foreach($stateUsers as $i => $user) {
$stateUsers[$i]->identHash = TransactionCreation::DRMakeStringHash($user->email);
}
$this->set('stateUsers', $stateUsers);
}
/**
* View method

View File

@ -11,10 +11,9 @@ use Cake\Datasource\ConnectionManager;
use App\Form\CreationForm;
// protobuf transactions
use Model\Messages\Gradido\TransactionCreation;
use Model\Messages\Gradido\TransactionBody;
use Model\Messages\Gradido\ReceiverAmount;
use Model\Messages\Gradido\TimestampSeconds;
//use Model\Messages\Gradido\TransactionCreation;
use Model\Transactions\TransactionCreation;
/**
* TransactionCreations Controller
*
@ -92,7 +91,7 @@ class TransactionCreationsController extends AppController
if($name === NULL) {
$name = $stateUser->first_name . ' ' . $stateUser->last_name;
}
array_push($receiverProposal, ['name' => $name, 'key' => $keyHex]);
array_push($receiverProposal, ['name' => $name, 'key' => $keyHex, 'email' => $stateUser->email]);
//$stateUser->public_key
}
$timeUsed = microtime(true) - $startTime;
@ -103,42 +102,23 @@ class TransactionCreationsController extends AppController
$mode = 'next';
if(isset($requestData['add'])) {$mode = 'add'; }
if($creationForm->validate($requestData)) {
$pubKeyHex = '';
$receiver = new ReceiverAmount();
$identHash = '';
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
$receiverIndex = intval($requestData['receiver'])-1;
$receiver->setAmount($this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']));
if(intval($requestData['receiver']) == 0) {
if(strlen($requestData['receiver_pubkey_hex']) != 64) {
$this->Flash->error(__('Invalid public Key, must contain 64 Character'));
} else {
$pubKeyHex = $requestData['receiver_pubkey_hex'];
}
} else {
$receiverIndex = intval($requestData['receiver'])-1;
if(count($receiverProposal) > $receiverIndex) {
$pubKeyHex = $receiverProposal[$receiverIndex]['key'];
}
if(count($receiverProposal) > $receiverIndex) {
$pubKeyHex = $receiverProposal[$receiverIndex]['key'];
$identHash = TransactionCreation::DRMakeStringHash($receiverProposal[$receiverIndex]['email']);
}
if($pubKeyHex != '') {
$pubKeyBin = hex2bin($pubKeyHex);
$receiver->setEd25519ReceiverPubkey($pubKeyBin);
//var_dump($requestData);
$creationDate = new TimestampSeconds();
$creationDate->setSeconds(time());
$transactionBody = new TransactionBody();
$transactionBody->setMemo($requestData['memo']);
$transactionBody->setCreated($creationDate);
$transaction = new TransactionCreation();
$transaction->setReceiverAmount($receiver);
$transaction->setIdentHash($user['ident_hash']);
$transactionBody->setCreation($transaction);
$builderResult = TransactionCreation::build(
$amountCent,
$requestData['memo'],
$pubKeyHex,
$identHash
);
if($builderResult['state'] == 'success') {
$http = new Client();
try {
@ -147,7 +127,7 @@ class TransactionCreationsController extends AppController
$session_id = $session->read('session_id');
$response = $http->get($url . '/checkTransaction', [
'session_id' => $session_id,
'transaction_base64' => base64_encode($transactionBody->serializeToString())
'transaction_base64' => base64_encode($builderResult['transactionBody']->serializeToString())
]);
$json = $response->getJson();
if($json['state'] != 'success') {
@ -262,7 +242,23 @@ class TransactionCreationsController extends AppController
if ($this->request->is('post')) {
$requestData = $this->request->getData();
var_dump($requestData);
// memo
// amount
$memo = $requestData['memo'];
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
if(!isset($requestData['user']) || count($requestData['user']) == 0) {
$this->Flash->error(__('no user choosen'));
} else {
$users = $requestData['user'];
var_dump($users);
$receiverUsers = $stateUserTable
->find('all')
->where(['id' => array_keys($users)])
->select(['public_key', 'email']);
//$identHash = TransactionCreation::DRMakeStringHash($receiverProposal[$receiverIndex]['email']);
}
}

View File

@ -45,10 +45,6 @@ class TransactionCreationsTable extends Table
'foreignKey' => 'state_user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('StateUsers', [
'foreignKey' => 'receiver_user_id',
'joinType' => 'INNER'
]);
}
/**

View File

@ -1,69 +1,69 @@
<?php
namespace Model\Transactions;
use Cake\ORM\TableRegistry;
class TransactionBase {
private $errors = [];
public function getErrors() {
return $this->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;
}
protected function updateStateBalance($stateUserId, $newAmountCent) {
$stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances');
$stateBalanceQuery = $stateBalancesTable
->find('all')
->select(['amount'])
->contain(false)
->where(['state_user_id' => $stateUserId]);//->first();
//debug($stateBalanceQuery);
if($stateBalanceQuery->count() > 0) {
$stateBalanceEntry = $stateBalanceQuery->first();
$stateBalanceEntry->amount += $newAmountCent;
} else {
$stateBalanceEntry = $stateBalancesTable->newEntity();
$stateBalanceEntry->state_user_id = $stateUserId;
$stateBalanceEntry->amount = $newAmountCent;
}
if(!$stateBalancesTable->save($stateBalanceEntry)) {
$errors = $stateBalanceEntry->getErrors();
$this->addError('TransactionBase::updateStateBalance', 'error saving state balance with: ' . json_encode($errors));
return false;
}
return true;
}
<?php
namespace Model\Transactions;
use Cake\ORM\TableRegistry;
class TransactionBase {
private $errors = [];
public function getErrors() {
return $this->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;
}
protected function updateStateBalance($stateUserId, $newAmountCent) {
$stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances');
$stateBalanceQuery = $stateBalancesTable
->find('all')
->select(['amount', 'id'])
->contain(false)
->where(['state_user_id' => $stateUserId]);//->first();
//debug($stateBalanceQuery);
if($stateBalanceQuery->count() > 0) {
$stateBalanceEntry = $stateBalanceQuery->first();
$stateBalanceEntry->amount += $newAmountCent;
} else {
$stateBalanceEntry = $stateBalancesTable->newEntity();
$stateBalanceEntry->state_user_id = $stateUserId;
$stateBalanceEntry->amount = $newAmountCent;
}
//echo "\ntry to save: "; var_dump($stateBalanceEntry); echo "\n";
if(!$stateBalancesTable->save($stateBalanceEntry)) {
$errors = $stateBalanceEntry->getErrors();
$this->addError('TransactionBase::updateStateBalance', 'error saving state balance with: ' . json_encode($errors));
return false;
}
return true;
}
}

View File

@ -10,10 +10,57 @@ class TransactionCreation extends TransactionBase {
private $protoTransactionCreation;
private $transactionCreationsTable;
private $receiver_pubkey_hex;
public function __construct($protoTransactionCreation) {
$this->protoTransactionCreation = $protoTransactionCreation;
$this->transactionCreationsTable = TableRegistry::getTableLocator()->get('transaction_creations');
$this->receiver_pubkey_hex = bin2hex($this->getReceiverPublic());
}
static public function build($amount, $memo, $receiver_public_hex, $ident_hash)
{
$receiver = new \Model\Messages\Gradido\ReceiverAmount();
$receiver->setAmount($amount);
$this->receiver_pubkey_hex = $receiver_public_hex;
if(strlen($receiver_public_hex) != 64) {
return ['state' => 'error', 'msg' => 'invalid pubkey'];
}
$pubKeyBin = hex2bin($receiver_public_hex);
$receiver->setEd25519ReceiverPubkey($pubKeyBin);
//var_dump($requestData);
$creationDate = new \Model\Messages\Gradido\TimestampSeconds();
$creationDate->setSeconds(time());
$transactionBody = new \Model\Messages\Gradido\TransactionBody();
$transactionBody->setMemo($memo);
$transactionBody->setCreated($creationDate);
$transaction = new \Model\Messages\Gradido\TransactionCreation();
$transaction->setReceiverAmount($receiver);
$transaction->setIdentHash($ident_hash);
$transactionBody->setCreation($transaction);
return ['state' => 'success', 'transactionBody' => $transactionBody];
}
static protected function DRHashRotateLeft( $hash, $rotateBy )
{
return ($hash<<$rotateBy)|($hash>>(32-$rotateBy));
}
static public function DRMakeStringHash($str)
{
$ret = 0;
if( $str )
{
for ($i=0; $i < strlen($str); $i++)
{
$ret = TransactionCreation::DRHashRotateLeft($ret, 7) + ord($str{$i});
}
}
return $ret;
}
public function getAmount() {
@ -28,6 +75,7 @@ class TransactionCreation extends TransactionBase {
return $this->protoTransactionCreation->getIdentHash();
}
public function validate($sigPairs) {
// check if receiver public is not in signature list
$receiverPublic = $this->getReceiverPublic();
@ -43,25 +91,33 @@ class TransactionCreation extends TransactionBase {
//$identHashBin = sprintf("%0d", $this->getIdentHash());
// padding with zero in case hash is smaller than 32 bytes, static length binary field in db
// ident hash isn't collision ressistent, it is for speed up search
$identHashBin = pack('a32', $this->getIdentHash());
$existingCreations = $this->transactionCreationsTable
->find('all')
->group('ident_hash')
->select(['amount', 'state_user_id'])
->contain(['StateUsers' => ['fields' => ['StateUsers.public_key']]])
->where(['ident_hash' => $identHashBin]);
$existingCreations->select(['amount_sum' => $existingCreations->func()->sum('amount')]);
//$existingCreations->select(['amount_sum' => $existingCreations->func()->sum('amount')]);
$existingCreations->select(['amount', 'state_user_id']);
$existingCreations->matching('Transactions', function ($q) {
return $q->where(['EXTRACT(YEAR_MONTH FROM Transactions.received) LIKE EXTRACT(YEAR_MONTH FROM NOW())']);
});
//debug($existingCreations);
if($existingCreations->count() > 0) {
//var_dump($existingCreations->toArray());
//echo "amount sum: " . $existingCreations->first()->amount_sum . "\n";
if($this->getAmount() + $existingCreations->first()->amount_sum > 10000000) {
$this->addError('TransactionCreation::validate', 'Creation more than 1000 gr per Month not allowed');
return false;
$newSum = $this->getAmount();
//var_dump($existingCreations->toArray());
foreach($existingCreations as $creation) {
$keyHex = bin2hex(stream_get_contents($creation->state_user->public_key));
//echo "\ncompare \n$keyHex\nwith: \n". $this->receiver_pubkey_hex."\n";
if($keyHex == $this->receiver_pubkey_hex) {
$newSum += $creation->amount;
}
}
}
if($newSum > 10000000) {
$this->addError('TransactionCreation::validate', 'Creation more than 1000 gr per Month not allowed');
return false;
}
//die("\n");
return true;
}

View File

@ -14,5 +14,5 @@ else if($number > 0) $class = "grd-positive-currency";*/
?>
<span class="<?php echo $class;?>">
<?= $this->Number->format(intval($number) / 10000.0, ['precision' => 2]) . ' grd';?>
<?= $this->Number->format(intval($number) / 10000.0, ['precision' => 2]) . ' GDD';?>
</span>

View File

@ -44,7 +44,7 @@ $this->assign('title', __('Schöpfungstransaktion'));
<?= $this->Form->control('amount'); ?>
<?php foreach($possibleReceiver as $possibleReceiver) : ?>
<div class="grd_big_checkbox">
<?= $this->Form->checkbox('user[' .$possibleReceiver['id'] . ']', ['hiddenField' => false]); ?>
<?= $this->Form->checkbox('user[' .$possibleReceiver['id'] . ']', ['value' => $possibleReceiver['id'], 'hiddenField' => false]); ?>
<?= $possibleReceiver['name'] ?>
<?php if($possibleReceiver['email'] != '') : ?>
&lt;<?= $possibleReceiver['email'] ?>&gt;

View File

@ -20,7 +20,7 @@ $this->assign('title', __('Überweisung'));
<?= $this->Form->create($creationForm) ?>
<div class="form-group row showcase_row_area">
<div class="col-md-3 showcase_text_area">
<label for="inputAmount">Betrag in grd</label>
<label for="inputAmount">Betrag in GDD</label>
</div>
<div class="col-md-9 showcase_content_area">
<input type="number" step="0.01" class="form-control" id="inputAmount" name="inputAmount" >

View File

@ -15,7 +15,7 @@ class StateBalancesFixture extends TestFixture
*/
// @codingStandardsIgnoreStart
public $fields = [
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => true],
'state_user_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'modified' => ['type' => 'datetime', 'length' => null, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null],
'amount' => ['type' => 'biginteger', 'length' => 20, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],

View File

@ -44,8 +44,8 @@ class StateUsersFixture extends TestFixture
'id' => 1,
'index_id' => 0,
'group_id' => 0,
'public_key' => '0x94ae135b93cd9f33752b4e55c41903a3faa13a75bb90bfd411ea1d4a1a5e711f',
'email' => NULL,
'public_key' => hex2bin('94ae135b93cd9f33752b4e55c41903a3faa13a75bb90bfd411ea1d4a1a5e711f'),
'email' => '***REMOVED***',
'first_name' => 'Dario',
'last_name' => 'Rekowski'
],
@ -53,8 +53,8 @@ class StateUsersFixture extends TestFixture
'id' => 11,
'index_id' => 0,
'group_id' => 0,
'public_key' => '0x61b923c218cb63a64a8c62f3860121283b9577f374d0a31590ba02cdc2912999',
'email' => NULL,
'public_key' => hex2bin('61b923c218cb63a64a8c62f3860121283b9577f374d0a31590ba02cdc2912999'),
'email' => 'em741@gmx.de',
'first_name' => 'Dario',
'last_name' => 'Rekowski'
],