From 23492e97bb7f21a186959f2f72bae308093c8dbb Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 2 Nov 2020 15:51:37 +0000 Subject: [PATCH] update pending tasks, creation and transfer --- .../insert/insert_transaction_types.sql | 10 +- .../gradido_community/transaction_types.sql | 2 +- src/Controller/AppController.php | 11 +- .../JsonRequestHandlerController.php | 37 ++++- .../TransactionCreationsController.php | 154 +++++++++++------- .../TransactionSendCoinsController.php | 5 + src/Template/Element/navi_notify.ctp | 21 ++- 7 files changed, 160 insertions(+), 80 deletions(-) diff --git a/skeema/gradido_community/insert/insert_transaction_types.sql b/skeema/gradido_community/insert/insert_transaction_types.sql index 9dbf5b93f..7cc2ebfdd 100644 --- a/skeema/gradido_community/insert/insert_transaction_types.sql +++ b/skeema/gradido_community/insert/insert_transaction_types.sql @@ -1,5 +1,9 @@ - INSERT INTO `transaction_types` (`id`, `name`, `text`) VALUES -(1, 'creation', 'Aktives oder Bedingungsloses Grundeinkommen.'), -(2, 'transfer', 'Einfache Überweisung'); +(1, 'group create', 'create a new group, trigger creation of new hedera topic and new blockchain on node server'), +(2, 'group add member', 'add user to a group or move if he was already in a group'), +(3, 'creation', 'create new gradidos for member and also for group (in development)'), +(4, 'transfer', 'send gradidos from one member to another, also cross group transfer'), +(5, 'hedera topic create', 'create new topic on hedera'), +(6, 'hedera topic send message', 'send consensus message over hedera topic'), +(7, 'hedera account create', 'create new account on hedera for holding some founds with unencrypted keys'); diff --git a/skeema/gradido_community/transaction_types.sql b/skeema/gradido_community/transaction_types.sql index 87492e1fe..a3e6779d9 100644 --- a/skeema/gradido_community/transaction_types.sql +++ b/skeema/gradido_community/transaction_types.sql @@ -1,6 +1,6 @@ CREATE TABLE `transaction_types` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(24) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, `text` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index 87ec7afb3..258ee565d 100644 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -129,6 +129,7 @@ class AppController extends Controller if ($this->Auth->user('id')) { $GLOBALS['ServerUser'] = $this->Auth->user(); } + // login server url $loginServer = Configure::read('LoginServer'); if ($loginServer && isset($loginServer['url'])) { @@ -159,12 +160,14 @@ class AppController extends Controller $userStored = $session->read('StateUser'); $transactionPendings = $session->read('Transaction.pending'); - $transactionExecutings = $session->read('Transaction.executing'); + $transactionExecutings = $session->read('Transaction.executing'); + $transaction_can_signed = $session->read('Transaction.can_signed'); if ($session->read('session_id') != $session_id || ( $userStored && (!isset($userStored['id']) || !$userStored['email_checked'])) || intval($transactionPendings) > 0 || - intval($transactionExecutings) > 0) { + intval($transactionExecutings) > 0 || + intval($transaction_can_signed > 0)) { $http = new Client(); try { @@ -188,9 +191,11 @@ class AppController extends Controller //var_dump($json); $transactionPendings = $json['Transaction.pending']; $transactionExecuting = $json['Transaction.executing']; + $transaction_can_signed = $json['Transaction.can_signed']; //echo "read transaction pending: $transactionPendings
"; $session->write('Transaction.pending', $transactionPendings); $session->write('Transaction.executing', $transactionExecuting); + $session->write('Transaction.can_signed', $transaction_can_signed); $session->write('session_id', $session_id); $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); @@ -204,7 +209,7 @@ class AppController extends Controller $stateUser = $stateUserQuery->first(); if ($stateUser->first_name != $json['user']['first_name'] || $stateUser->last_name != $json['user']['last_name'] || - $stateUser->disabled != intval($json['user']['disabled']) || + $stateUser->disabled != $json['user']['disabled'] || //$stateUser->username != $json['user']['username'] || // -> throws error $stateUser->email != $json['user']['email'] diff --git a/src/Controller/JsonRequestHandlerController.php b/src/Controller/JsonRequestHandlerController.php index 76bff2324..a0a0748c5 100644 --- a/src/Controller/JsonRequestHandlerController.php +++ b/src/Controller/JsonRequestHandlerController.php @@ -58,7 +58,7 @@ class JsonRequestHandlerController extends AppController { case 'checkUser': return $this->checkUser($jsonData->email, $jsonData->last_name); case 'getUsers' : return $this->getUsers($jsonData->page, $jsonData->limit); case 'getUserBalance': return $this->getUserBalance($jsonData->email, $jsonData->last_name); - case 'errorInTransaction': return $this->errorInTransaction($jsonData->created, $jsonData->transactionGenericHash, $jsonData->error, $jsonData->errorMessage); + case 'errorInTransaction': return $this->errorInTransaction($jsonData); } return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for post', 'details' => $method]); } @@ -71,16 +71,45 @@ class JsonRequestHandlerController extends AppController { //! using sodium_crypto_generichash to calculate // hash also in base64 format //! \param $error short error name in user language - //! \param $errorDetails more detailed error message in user language - private function errorInTransaction($transactionCreated, $transactionBodyBase64GenericHash, $error, $errorDetails) { + //! \param $errorDetails more detailed error message in user language + private function errorInTransaction($jsonData) { /* * payload.set("created", created); * payload.set("id", task_model->getID()); + * payload.set("type", task_model->getTaskTypeString()); * payload.set("public_key", user_model->getPublicKeyHex()); * payload.set("error", error); * payload.set("errorMessage", errorDetails); */ - + $stateErrorTable = TableRegistry::getTableLocator()->get('StateErrors'); + $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers'); + $transactionTypesTable = TableRegistry::getTableLocator()->get('TransactionTypes'); + $stateError = $stateErrorTable->newEntity(); + // + $pubkey = hex2bin($jsonData->public_key); + $user_query = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $pubkey]); + if($user_query->count() != 1) { + return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'user pubkey hex:' . $jsonData->public_key]); + } + $stateError->state_user_id = $user_query->first()->id; + //$stateError->transaction_type_id + // TODO: + // - show state errors in navi_notify.ctp + $transaction_type_query = $transactionTypesTable->find('all')->select(['id'])->where(['name' => $jsonData->type]); + if($transaction_type_query->count() != 1) { + return $this->returnJson(['state' => 'error', 'msg' => 'transaction type not found', 'details' => 'transaction type name: ' . $jsonData->type]); + } + $stateError->transaction_type_id = $transaction_type_query->first()->id; + $stateError->created = $jsonData->created; + $stateError->message_json = json_encode(['task_id' => $jsonData->id, 'error' => $jsonData->error, 'errorMessage' => $jsonData->errorMessage]); + if(!$stateErrorTable->save($stateError)) { + $this->returnJsonSaveError($stateError, [ + 'state' => 'error', + 'msg' => 'error saving state_error in db', + 'details' => json_encode($stateError->getErrors()) + ]); + } + return $this->returnJson(['state' => 'success']); } private function putTransaction($transactionBase64) { diff --git a/src/Controller/TransactionCreationsController.php b/src/Controller/TransactionCreationsController.php index 5e29a7997..5acfce2d7 100644 --- a/src/Controller/TransactionCreationsController.php +++ b/src/Controller/TransactionCreationsController.php @@ -335,6 +335,7 @@ class TransactionCreationsController extends AppController if (isset($requestData['add'])) { $mode = 'add'; } + //echo "mode: $mode
"; $memo = $requestData['memo']; $amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']); //$targetDate = $requestData['target_date']; @@ -342,17 +343,20 @@ class TransactionCreationsController extends AppController $this->Flash->error(__('No user selected')); } else { $users = $requestData['user']; + $pendingTransactionCount = $session->read('Transactions.pending'); + if ($pendingTransactionCount == null) { + $pendingTransactionCount = 0; + } if (isset($requestData['user_pending'])) { $pendings = $requestData['user_pending']; } else { $pendings = []; } - $receiverUsers = $stateUserTable - ->find('all') - ->where(['id IN' => array_keys($users)]) - ->select(['public_key', 'email', 'id']) - ->contain(false); - $transactions = []; + $receiverUsers = $stateUserTable->find('all') + ->where(['id IN' => array_keys($users)]) + ->select(['public_key', 'email', 'id']) + ->contain(false); + foreach ($receiverUsers as $receiverUser) { $localAmountCent = $amountCent; //$localTargetDate = $targetDate; @@ -369,25 +373,87 @@ class TransactionCreationsController extends AppController $pendings[$id] = $localAmountCent; } $pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key)); - $identHash = TransactionCreation::DRMakeStringHash($receiverUser->email); + $localTargetDateFrozen = FrozenDate::now(); $localTargetDateFrozen = $localTargetDateFrozen - ->year($localTargetDate['year']) - ->month($localTargetDate['month']) - ->day($localTargetDate['day']); - //echo "input: "; var_dump($localTargetDate);echo "
"; - //echo "output: "; var_dump($localTargetDateFrozen); - //die('a'); - $builderResult = TransactionCreation::build( - $localAmountCent, - $memo, - $pubKeyHex, - $identHash, - $localTargetDateFrozen - ); - if ($builderResult['state'] == 'success') { - array_push($transactions, base64_encode($builderResult['transactionBody']->serializeToString())); + ->year($localTargetDate['year']) + ->month($localTargetDate['month']) + ->day($localTargetDate['day']); + + $requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([ + 'session_id' => $session->read('session_id'), + 'transaction_type' => 'creation', + 'memo' => $memo, + 'amount' => $localAmountCent, + 'target_pubkey' => $pubKeyHex, + 'target_date' => $localTargetDateFrozen + ]), '/createTransaction'); + + if('success' != $requestAnswear['state']) { + $this->addAdminError('TransactionCreations', 'createMulti', $requestAnswear, $user['id']); + if ($requestResult['type'] == 'request error') { + $this->Flash->error(__('Error by requesting LoginServer, please try again')); + } else { + $this->Flash->error(__('Error, please wait for the admin to fix it')); + } } + if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) { + $pendingTransactionCount++; + //echo "pending transaction count: $pendingTransactionCount
"; + } else { + /* + * if request contain unknown parameter format, shouldn't happen't at all + * {"state": "error", "msg": "parameter format unknown"} + * if json parsing failed + * {"state": "error", "msg": "json exception", "details":"exception text"} + * if session_id is zero or not set + * {"state": "error", "msg": "session_id invalid"} + * if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes) + * {"state": "error", "msg": "session not found"} + * if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen + * {"state": "code error", "msg":"user is zero"} + * if transaction type not known + * {"state": "error", "msg":"transaction_type unknown"} + * if receiver wasn't known to Login-Server + * {"state": "not found", "msg":"receiver not found"} + * if receiver account disabled, and therefor cannto receive any coins + * {"state": "disabled", "msg":"receiver is disabled"} + * if amount is invalid in creation + * {"state": "invalid parameter", "msg":"invalid amount", "details":"GDD amount in GDD cent ]0,10000000]"} + * if transaction was okay and will be further proccessed + * {"state":"success"} + */ + $answear_data = $requestAnswear['data']; + if($answear_data['state'] === 'error') { + if($answear_data['msg'] === 'session_id invalid' || $answear_data['msg'] === 'session not found') { + $this->Flash->error(__('Fehler mit der Session, bitte logge dich erneut ein!')); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } + if($answear_data['msg'] === 'user not in group') { + $this->Flash->error(__('Fehler, Benutzer gehört zu einer anderen Gruppe!')); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } + } else if($answear_data['state'] === 'not found' && $answear_data['msg'] === 'receiver not found') { + $this->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?')); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } else if($answear_data['state'] === 'disabled') { + $this->Flash->error(__('Der Empfänger ist deaktiviert, daher können ihm zurzeit keine Gradidos gesendet werden.')); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } else if($answear_data['msg'] === 'invalid amount') { + $this->Flash->error(__('Der Betrag ist ungültig, er muss größer als 0 und <= 1000 sein.')); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } else { + $this->Flash->error(__('Unbehandelter Fehler: ') . json_encode($answear_data)); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } + } + } /*echo "pendings: "; var_dump($pendings); @@ -399,49 +465,17 @@ class TransactionCreationsController extends AppController } } $this->set('possibleReceivers', $possibleReceivers); - $creationTransactionCount = count($transactions); - if ($creationTransactionCount > 0) { + if ($pendingTransactionCount > 0) { $user_balance = 0; if (isset($user['balance'])) { $user_balance = $user['balance']; } - // $session_id, $base64Message, $user_balance = 0 - $requestResult = $this->JsonRequestClient->sendTransaction( - $session->read('session_id'), - $transactions, - $user_balance - ); - if ($requestResult['state'] != 'success') { - $this->addAdminError('TransactionCreations', 'createMulti', $requestResult, $user['id']); - if ($requestResult['type'] == 'request error') { - $this->Flash->error(__('Error by requesting LoginServer, please try again')); - } else { - $this->Flash->error(__('Error, please wait for the admin to fix it')); - } + $session->write('Transactions.pending', $pendingTransactionCount); + + if ($mode === 'next') { + return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303); } else { - $json = $requestResult['data']; - if ($json['state'] != 'success') { - if ($json['msg'] == 'session not found') { - $session->destroy(); - return $this->redirect($this->loginServerUrl . 'account', 303); - } else { - $this->addAdminError('TransactionCreations', 'createMulti', $json, $user['id']); - $this->Flash->error(__('Login Server Error, please wait for the admin to fix it')); - } - } else { - $pendingTransactionCount = $session->read('Transactions.pending'); - if ($pendingTransactionCount == null) { - $pendingTransactionCount = $creationTransactionCount; - } else { - $pendingTransactionCount += $creationTransactionCount; - } - $session->write('Transactions.pending', $pendingTransactionCount); - if ($mode === 'next') { - return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303); - } else { - $this->Flash->success(__('Transaction submitted for review.')); - } - } + $this->Flash->success(__('Transaction submitted for review.')); } } } diff --git a/src/Controller/TransactionSendCoinsController.php b/src/Controller/TransactionSendCoinsController.php index 90c6dc670..39d1eea1b 100644 --- a/src/Controller/TransactionSendCoinsController.php +++ b/src/Controller/TransactionSendCoinsController.php @@ -230,6 +230,11 @@ class TransactionSendCoinsController extends AppController $this->set('timeUsed', microtime(true) - $startTime); return; } + if($answear_data['msg'] === 'user not in group') { + $this->Flash->error(__('Empfänger befindet sich nicht in Zielgruppe!')); + $this->set('timeUsed', microtime(true) - $startTime); + return; + } } else if($answear_data['state'] === 'not found' && $answear_data['msg'] === 'receiver not found') { $this->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?')); $this->set('timeUsed', microtime(true) - $startTime); diff --git a/src/Template/Element/navi_notify.ctp b/src/Template/Element/navi_notify.ctp index 35687687d..61e6cdd5b 100644 --- a/src/Template/Element/navi_notify.ctp +++ b/src/Template/Element/navi_notify.ctp @@ -11,6 +11,7 @@ use Cake\Routing\Router; $session = $this->getRequest()->getSession(); $errorCount = intval($session->read('StateUser.errorCount')); $transactionPendings = $session->read('Transactions.pending'); +$transactionPendings += $session->read('Transaction.can_signed'); /* class NavHeaderEntry @@ -23,19 +24,21 @@ class NavHeaderEntry } */ ?> + 0) : ?> + Html->link( + 'announcement' + . 'ss', + ['controller' => 'StateErrors', 'action' => 'ShowForUser'], + ['class' => 'nav-link', 'escape' => false, 'title' => "$errorCount " . __('Fehler')]) ?> + 0) : ?> - " href="account/checkTransactions"> - verified_user + " href="account/checkTransactions"> + verified_user - + () + - 0) : ?> - Html->link( - 'announcement', - ['controller' => 'StateErrors', 'action' => 'ShowForUser'], - ['class' => 'notify-link', 'escape' => false, 'title' => "$errorCount " . __('Fehler')]) ?> -