From da8487337937aa2da2c6ddb8b76956c8498567b1 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Wed, 4 Dec 2019 16:10:08 +0000 Subject: [PATCH] update transfer --- config/ripple_horizontal_form.php | 22 +++- .../TransactionSendCoinsController.php | 116 +++++++++++++++++- src/Form/CreationForm.php | 3 +- src/Form/TransferForm.php | 79 +++++++++++- .../Transactions/TransactionCreation.php | 2 +- .../Transactions/TransactionTransfer.php | 46 ++++++- .../Validation/TransactionValidation.php | 9 +- src/Template/Element/navi_header.ctp | 4 +- src/Template/TransactionSendCoins/create.ctp | 58 ++++----- webroot/css/rippleUI/style.css | 2 +- 10 files changed, 290 insertions(+), 51 deletions(-) diff --git a/config/ripple_horizontal_form.php b/config/ripple_horizontal_form.php index 09d593bdd..de38a8b3c 100644 --- a/config/ripple_horizontal_form.php +++ b/config/ripple_horizontal_form.php @@ -9,15 +9,35 @@ return [ // Container element used by control(). 'inputContainer' => '
{{content}}
', + // Container element used by control() when a field has an error. + //'inputContainerError' => '
{{content}}{{error}}
', + 'inputContainerError' => '
{{content}}{{error}}
', // Label element when inputs are not nested inside the label. 'label' => '
' . '{{text}}' . '
', // Generic input element. 'input' => '
' - . '' + . '' + . '
', + // Textarea input element, + 'textarea' => '
' + . '' + . '
', + // Error message wrapper elements. + //'error' => '
{{content}}
', + //'error' => '{{content}}', + 'error' => '
' + . '{{content}}' . '
', + // Container for error items. + //'errorList' => '', + 'errorList' => '{{content}}', + + // Error item wrapper. + //'errorItem' => '
  • {{text}}
  • ', + 'errorItem' => '
    {{text}}
    ' ]; /* diff --git a/src/Controller/TransactionSendCoinsController.php b/src/Controller/TransactionSendCoinsController.php index 085b34f59..d3b30dc7c 100644 --- a/src/Controller/TransactionSendCoinsController.php +++ b/src/Controller/TransactionSendCoinsController.php @@ -2,8 +2,14 @@ namespace App\Controller; use App\Controller\AppController; -use App\Form\CreationForm; +use Cake\ORM\TableRegistry; +use Cake\Http\Client; +use Cake\Core\Configure; +use Cake\Routing\Router; +use App\Form\TransferForm; + +use Model\Transactions\TransactionTransfer; /** * TransactionSendCoins Controller * @@ -118,12 +124,114 @@ class TransactionSendCoinsController extends AppController } $user = $session->read('StateUser'); } + + $transferForm = new TransferForm(); + $this->set('transferForm', $transferForm); + $this->set('timeUsed', microtime(true) - $startTime); + if ($this->request->is('post')) { - $this->Flash->error(__('Wird zurzeit noch entwickelt!')); + //$this->Flash->error(__('Wird zurzeit noch entwickelt!')); + + $requestData = $this->request->getData(); + $mode = 'next'; + if(isset($requestData['add'])) {$mode = 'add'; } + if($transferForm->validate($requestData)) { + + $receiverPubKeyHex = ''; + $senderPubKeyHex = $user['public_hex']; + $amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']); + + if(!isset($user['balance']) || $amountCent > $user['balance']) { + $this->Flash->error(__('Du hast nicht genug Geld!')); + return; + } + + $receiverEmail = $requestData['email']; + if($receiverEmail === $user['email']) { + $this->Flash->error(__('Du kannst dir leider nicht selbst Geld schicken!')); + return; + } + + $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); + $receiverUser = $stateUserTable + ->find('all') + ->select(['public_key']) + ->contain(false) + ->where(['email' => $receiverEmail])->first(); + //var_dump($receiverUser); + if(!$receiverUser) { + $this->Flash->error(__('Diese E-Mail ist mir nicht bekannt, hat dein Empfänger denn schon ein Gradido-Konto?')); + return; + } + $receiverPubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key)); + //var_dump($sessionStateUser); + + $builderResult = TransactionTransfer::build( + $amountCent, + $requestData['memo'], + $receiverPubKeyHex, + $senderPubKeyHex + ); + if($builderResult['state'] === 'success') { + + $http = new Client(); + try { + $loginServer = Configure::read('LoginServer'); + $url = $loginServer['host'] . ':' . $loginServer['port']; + $session_id = $session->read('session_id'); + /* + * + * $response = $http->post( + * 'http://example.com/tasks', + * json_encode($data), + * ['type' => 'json'] + * ); + */ + $response = $http->post($url . '/checkTransaction', json_encode([ + 'session_id' => $session_id, + 'transaction_base64' => base64_encode($builderResult['transactionBody']->serializeToString()), + 'balance' => $user['balance'] + ]), ['type' => 'json']); + $json = $response->getJson(); + if($json['state'] != 'success') { + if($json['msg'] == 'session not found') { + $session->destroy(); + return $this->redirect(Router::url('/', true) . 'account', 303); + //$this->Flash->error(__('session not found, please login again')); + } else { + $this->Flash->error(__('login server return error: ' . json_encode($json))); + } + } else { + $pendingTransactionCount = $session->read('Transactions.pending'); + if($pendingTransactionCount == null) { + $pendingTransactionCount = 1; + } else { + $pendingTransactionCount++; + } + $session->write('Transactions.pending', $pendingTransactionCount); + //echo "pending: " . $pendingTransactionCount; + if($mode === 'next') { + return $this->redirect(Router::url('/', true) . 'account/checkTransactions', 303); + } else { + $this->Flash->success(__('Transaction submitted for review.')); + } + } + + } catch(\Exception $e) { + $msg = $e->getMessage(); + $this->Flash->error(__('error http request: ') . $msg); + } + + } else { + $this->Flash->error(__('No Valid Receiver Public given')); + } + +// */ + } else { + $this->Flash->error(__('Something was invalid, please try again!')); + } } - $creationForm = new CreationForm(); - $this->set('creationForm', $creationForm); $this->set('timeUsed', microtime(true) - $startTime); } diff --git a/src/Form/CreationForm.php b/src/Form/CreationForm.php index 46363de27..fbb4a4ded 100644 --- a/src/Form/CreationForm.php +++ b/src/Form/CreationForm.php @@ -39,7 +39,8 @@ class CreationForm extends Form ->add('memo', 'custom', [ 'rule' => 'alphaNumeric', 'provider' => 'custom', - 'message' => __('Only Alpha Numeric Character allowed') + //'message' => __('Only Alpha Numeric Character allowed') + 'message' => __('No HTML Tags like > or < please.') ]) ->allowEmptyString('memo', null, 'create') /*->add('receiver_pubkey_hex', 'custom', [ diff --git a/src/Form/TransferForm.php b/src/Form/TransferForm.php index 3ac00faa6..3919c177a 100644 --- a/src/Form/TransferForm.php +++ b/src/Form/TransferForm.php @@ -1,8 +1,75 @@ -addField('email', ['type' => 'string']) + ->addField('amount', ['type' => 'decimal', 'precision' => 2]) + ->addField('memo', ['type' =>'text', 'default' => '', 'rows' => 5, 'maxlength' => 150]); + } + + function validationDefault(Validator $validator) + { + $validator->setProvider('custom', 'App\Model\Validation\TransactionValidation'); + /* + $validator->add('receiver_pubkey_hex', 'length', [ + 'rule' => ['length', 64], + 'message' => 'a valid pubkey in hex format is required (64 character)' + ])->add('receiver_pubkey_hex_select', 'length', [ + 'rule' => ['length', 64], + 'message' => 'a valid pubkey in hex format is required (64 character)', + ]); +*/ + // TODO: add validation for used character to prevent hacking attempts + $validator->add('email', 'format', [ + 'rule' => 'email', + 'message' => __('A valid email address is required') + ]) + ->add('memo', 'length', [ + 'rule' => ['maxLength', 150], + 'message' => __('The memo should contain max 150 character') + ]) + //->alphaNumeric('memo', __('Only Alpha Numeric Character allowed')) + ->add('memo', 'custom', [ + 'rule' => 'alphaNumeric', + 'provider' => 'custom', + //'message' => __('Only Alpha Numeric Character allowed') + 'message' => __('No HTML Tags like > or < please.') + ]) + ->allowEmptyString('memo', null, 'create') + /*->add('receiver_pubkey_hex', 'custom', [ + 'rule' => 'hexKey64', + 'provider' => 'custom', + 'message' => 'a valid pubkey in hex format is required (64 character)' + ]) + ->allowEmptyString('receiver_pubkey_hex', null, 'create')*/ + ->add('amount', 'custom', [ + 'rule' => 'amount', + 'provider' => 'custom', + 'message' => __('Please give a valid positive number with maximal 2 decimal places') + ]); + return $validator; + } + /* + * $validator->add('title', 'custom', [ + 'rule' => 'customRule', + 'provider' => 'custom', + 'message' => 'The title is not unique enough' +]); + */ + + protected function _execute(array $data) + { + // Send an email. + return true; + } +} \ No newline at end of file diff --git a/src/Model/Transactions/TransactionCreation.php b/src/Model/Transactions/TransactionCreation.php index d495556fb..48e116c78 100644 --- a/src/Model/Transactions/TransactionCreation.php +++ b/src/Model/Transactions/TransactionCreation.php @@ -22,7 +22,7 @@ class TransactionCreation extends TransactionBase { { $receiver = new \Model\Messages\Gradido\ReceiverAmount(); $receiver->setAmount($amount); - $this->receiver_pubkey_hex = $receiver_public_hex; + //$this->receiver_pubkey_hex = $receiver_public_hex; if(strlen($receiver_public_hex) != 64) { return ['state' => 'error', 'msg' => 'invalid pubkey']; } diff --git a/src/Model/Transactions/TransactionTransfer.php b/src/Model/Transactions/TransactionTransfer.php index 89eb36bda..82ec9da9f 100644 --- a/src/Model/Transactions/TransactionTransfer.php +++ b/src/Model/Transactions/TransactionTransfer.php @@ -6,17 +6,59 @@ namespace Model\Transactions; class TransactionTransfer extends TransactionBase { private $protoTransactionTransfer; + private $receiver_pubkey_hex; + private $sender_pubkey_hex; public function __construct($protoTransactionTransfer) { $this->protoTransactionTransfer = $protoTransactionTransfer; } + static public function build($amount, $memo, $receiver_public_hex, $sender_public_hex) + { + // repeated SenderAmount senderAmounts = 1; + // repeated ReceiverAmount receiverAmounts = 2; + $receiver = new \Model\Messages\Gradido\ReceiverAmount(); + $sender = new \Model\Messages\Gradido\SenderAmount(); + $receiver->setAmount($amount); + $sender->setAmount($amount); + + if(strlen($receiver_public_hex) != 64) { + return ['state' => 'error', 'msg' => 'invalid receiver pubkey']; + } + if(strlen($sender_public_hex) != 64) { + return ['state' => 'error', 'msg' => 'invalid sender pubkey']; + } + $receiverPubKeyBin = hex2bin($receiver_public_hex); + $receiver->setEd25519ReceiverPubkey($receiverPubKeyBin); + + $senderPubKeyBin = hex2bin($sender_public_hex); + $sender->setEd25519SenderPubkey($senderPubKeyBin); + //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\Transfer(); + $transaction->setReceiverAmounts([$receiver]); + $transaction->setSenderAmounts([$sender]); + $transactionBody->setTransfer($transaction); + return ['state' => 'success', 'transactionBody' => $transactionBody]; + } + public function validate($sigPairs) { - return true; + $this->addError('TransactionTransfer::validate', 'not implemented yet'); + return false; + //return true; } public function save($transaction_id, $firstPublic) { - return true; + $this->addError('TransactionTransfer::save', 'not implemented yet'); + return false; + //return true; } } diff --git a/src/Model/Validation/TransactionValidation.php b/src/Model/Validation/TransactionValidation.php index a3463cd5b..cea00f123 100644 --- a/src/Model/Validation/TransactionValidation.php +++ b/src/Model/Validation/TransactionValidation.php @@ -20,7 +20,7 @@ class TransactionValidation $floatVal = floatval(Number::format($value, ['places' => 4, 'locale' => 'en_GB'])); //echo "floatVal: $floatVal
    "; - return $floatVal != 0.0; + return $floatVal >= 0.0; } public static function hexKey64($value, array $context) { @@ -32,9 +32,10 @@ class TransactionValidation } public static function alphaNumeric($value, array $context) { - if(preg_match('/^[a-zA-Z0-9äöüÄÖÜß _-]*$/', $value)) { - return true; + //if(preg_match('/^[a-zA-Z0-9äöüÄÖÜß _;:()-]\n\r*$/', $value)) { + if(preg_match('/([<>]|>|<|javascript:){1,}/', $value)) { + return false; } - return false; + return true; } } \ No newline at end of file diff --git a/src/Template/Element/navi_header.ctp b/src/Template/Element/navi_header.ctp index b3b8d4129..cbc2eea97 100644 --- a/src/Template/Element/navi_header.ctp +++ b/src/Template/Element/navi_header.ctp @@ -30,12 +30,12 @@ class NavHeaderEntry '' . '', ['controller' => 'StateErrors', 'action' => 'ShowForUser'], - ['class' => 'nav-link', 'escape' => false, 'title' => "($errorCount) " . __('Fehler')]) ?> + ['class' => 'nav-link', 'escape' => false, 'title' => "$errorCount " . __('Fehler')]) ?> 0) : ?>