update pending tasks, creation and transfer

This commit is contained in:
Dario Rekowski on RockPI 2020-11-02 15:51:37 +00:00 committed by Ulf Gebhardt
parent 968d8d98e8
commit 23492e97bb
No known key found for this signature in database
GPG Key ID: 81308EFE29ABFEBD
7 changed files with 160 additions and 80 deletions

View File

@ -1,5 +1,9 @@
INSERT INTO `transaction_types` (`id`, `name`, `text`) VALUES INSERT INTO `transaction_types` (`id`, `name`, `text`) VALUES
(1, 'creation', 'Aktives oder Bedingungsloses Grundeinkommen.'), (1, 'group create', 'create a new group, trigger creation of new hedera topic and new blockchain on node server'),
(2, 'transfer', 'Einfache Überweisung'); (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');

View File

@ -1,6 +1,6 @@
CREATE TABLE `transaction_types` ( CREATE TABLE `transaction_types` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `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, `text` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@ -129,6 +129,7 @@ class AppController extends Controller
if ($this->Auth->user('id')) { if ($this->Auth->user('id')) {
$GLOBALS['ServerUser'] = $this->Auth->user(); $GLOBALS['ServerUser'] = $this->Auth->user();
} }
// login server url // login server url
$loginServer = Configure::read('LoginServer'); $loginServer = Configure::read('LoginServer');
if ($loginServer && isset($loginServer['url'])) { if ($loginServer && isset($loginServer['url'])) {
@ -160,11 +161,13 @@ class AppController extends Controller
$transactionPendings = $session->read('Transaction.pending'); $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 || if ($session->read('session_id') != $session_id ||
( $userStored && (!isset($userStored['id']) || !$userStored['email_checked'])) || ( $userStored && (!isset($userStored['id']) || !$userStored['email_checked'])) ||
intval($transactionPendings) > 0 || intval($transactionPendings) > 0 ||
intval($transactionExecutings) > 0) { intval($transactionExecutings) > 0 ||
intval($transaction_can_signed > 0)) {
$http = new Client(); $http = new Client();
try { try {
@ -188,9 +191,11 @@ class AppController extends Controller
//var_dump($json); //var_dump($json);
$transactionPendings = $json['Transaction.pending']; $transactionPendings = $json['Transaction.pending'];
$transactionExecuting = $json['Transaction.executing']; $transactionExecuting = $json['Transaction.executing'];
$transaction_can_signed = $json['Transaction.can_signed'];
//echo "read transaction pending: $transactionPendings<br>"; //echo "read transaction pending: $transactionPendings<br>";
$session->write('Transaction.pending', $transactionPendings); $session->write('Transaction.pending', $transactionPendings);
$session->write('Transaction.executing', $transactionExecuting); $session->write('Transaction.executing', $transactionExecuting);
$session->write('Transaction.can_signed', $transaction_can_signed);
$session->write('session_id', $session_id); $session->write('session_id', $session_id);
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
@ -204,7 +209,7 @@ class AppController extends Controller
$stateUser = $stateUserQuery->first(); $stateUser = $stateUserQuery->first();
if ($stateUser->first_name != $json['user']['first_name'] || if ($stateUser->first_name != $json['user']['first_name'] ||
$stateUser->last_name != $json['user']['last_name'] || $stateUser->last_name != $json['user']['last_name'] ||
$stateUser->disabled != intval($json['user']['disabled']) || $stateUser->disabled != $json['user']['disabled'] ||
//$stateUser->username != $json['user']['username'] || //$stateUser->username != $json['user']['username'] ||
// -> throws error // -> throws error
$stateUser->email != $json['user']['email'] $stateUser->email != $json['user']['email']

View File

@ -58,7 +58,7 @@ class JsonRequestHandlerController extends AppController {
case 'checkUser': return $this->checkUser($jsonData->email, $jsonData->last_name); case 'checkUser': return $this->checkUser($jsonData->email, $jsonData->last_name);
case 'getUsers' : return $this->getUsers($jsonData->page, $jsonData->limit); case 'getUsers' : return $this->getUsers($jsonData->page, $jsonData->limit);
case 'getUserBalance': return $this->getUserBalance($jsonData->email, $jsonData->last_name); 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]); return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for post', 'details' => $method]);
} }
@ -72,15 +72,44 @@ class JsonRequestHandlerController extends AppController {
// hash also in base64 format // hash also in base64 format
//! \param $error short error name in user language //! \param $error short error name in user language
//! \param $errorDetails more detailed error message in user language //! \param $errorDetails more detailed error message in user language
private function errorInTransaction($transactionCreated, $transactionBodyBase64GenericHash, $error, $errorDetails) { private function errorInTransaction($jsonData) {
/* /*
* payload.set("created", created); * payload.set("created", created);
* payload.set("id", task_model->getID()); * payload.set("id", task_model->getID());
* payload.set("type", task_model->getTaskTypeString());
* payload.set("public_key", user_model->getPublicKeyHex()); * payload.set("public_key", user_model->getPublicKeyHex());
* payload.set("error", error); * payload.set("error", error);
* payload.set("errorMessage", errorDetails); * 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) { private function putTransaction($transactionBase64) {

View File

@ -335,6 +335,7 @@ class TransactionCreationsController extends AppController
if (isset($requestData['add'])) { if (isset($requestData['add'])) {
$mode = 'add'; $mode = 'add';
} }
//echo "mode: $mode<br>";
$memo = $requestData['memo']; $memo = $requestData['memo'];
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']); $amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
//$targetDate = $requestData['target_date']; //$targetDate = $requestData['target_date'];
@ -342,17 +343,20 @@ class TransactionCreationsController extends AppController
$this->Flash->error(__('No user selected')); $this->Flash->error(__('No user selected'));
} else { } else {
$users = $requestData['user']; $users = $requestData['user'];
$pendingTransactionCount = $session->read('Transactions.pending');
if ($pendingTransactionCount == null) {
$pendingTransactionCount = 0;
}
if (isset($requestData['user_pending'])) { if (isset($requestData['user_pending'])) {
$pendings = $requestData['user_pending']; $pendings = $requestData['user_pending'];
} else { } else {
$pendings = []; $pendings = [];
} }
$receiverUsers = $stateUserTable $receiverUsers = $stateUserTable->find('all')
->find('all')
->where(['id IN' => array_keys($users)]) ->where(['id IN' => array_keys($users)])
->select(['public_key', 'email', 'id']) ->select(['public_key', 'email', 'id'])
->contain(false); ->contain(false);
$transactions = [];
foreach ($receiverUsers as $receiverUser) { foreach ($receiverUsers as $receiverUser) {
$localAmountCent = $amountCent; $localAmountCent = $amountCent;
//$localTargetDate = $targetDate; //$localTargetDate = $targetDate;
@ -369,26 +373,88 @@ class TransactionCreationsController extends AppController
$pendings[$id] = $localAmountCent; $pendings[$id] = $localAmountCent;
} }
$pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key)); $pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key));
$identHash = TransactionCreation::DRMakeStringHash($receiverUser->email);
$localTargetDateFrozen = FrozenDate::now(); $localTargetDateFrozen = FrozenDate::now();
$localTargetDateFrozen = $localTargetDateFrozen $localTargetDateFrozen = $localTargetDateFrozen
->year($localTargetDate['year']) ->year($localTargetDate['year'])
->month($localTargetDate['month']) ->month($localTargetDate['month'])
->day($localTargetDate['day']); ->day($localTargetDate['day']);
//echo "input: "; var_dump($localTargetDate);echo "<br>";
//echo "output: "; var_dump($localTargetDateFrozen); $requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
//die('a'); 'session_id' => $session->read('session_id'),
$builderResult = TransactionCreation::build( 'transaction_type' => 'creation',
$localAmountCent, 'memo' => $memo,
$memo, 'amount' => $localAmountCent,
$pubKeyHex, 'target_pubkey' => $pubKeyHex,
$identHash, 'target_date' => $localTargetDateFrozen
$localTargetDateFrozen ]), '/createTransaction');
);
if ($builderResult['state'] == 'success') { if('success' != $requestAnswear['state']) {
array_push($transactions, base64_encode($builderResult['transactionBody']->serializeToString())); $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<br>";
} 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: "; /*echo "pendings: ";
var_dump($pendings); var_dump($pendings);
echo "<br>";*/ echo "<br>";*/
@ -399,43 +465,13 @@ class TransactionCreationsController extends AppController
} }
} }
$this->set('possibleReceivers', $possibleReceivers); $this->set('possibleReceivers', $possibleReceivers);
$creationTransactionCount = count($transactions); if ($pendingTransactionCount > 0) {
if ($creationTransactionCount > 0) {
$user_balance = 0; $user_balance = 0;
if (isset($user['balance'])) { if (isset($user['balance'])) {
$user_balance = $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'));
}
} 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); $session->write('Transactions.pending', $pendingTransactionCount);
if ($mode === 'next') { if ($mode === 'next') {
return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303); return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
} else { } else {
@ -445,8 +481,6 @@ class TransactionCreationsController extends AppController
} }
} }
} }
}
}
public function ajaxCreate() public function ajaxCreate()
{ {

View File

@ -230,6 +230,11 @@ class TransactionSendCoinsController extends AppController
$this->set('timeUsed', microtime(true) - $startTime); $this->set('timeUsed', microtime(true) - $startTime);
return; 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') { } 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->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?'));
$this->set('timeUsed', microtime(true) - $startTime); $this->set('timeUsed', microtime(true) - $startTime);

View File

@ -11,6 +11,7 @@ use Cake\Routing\Router;
$session = $this->getRequest()->getSession(); $session = $this->getRequest()->getSession();
$errorCount = intval($session->read('StateUser.errorCount')); $errorCount = intval($session->read('StateUser.errorCount'));
$transactionPendings = $session->read('Transactions.pending'); $transactionPendings = $session->read('Transactions.pending');
$transactionPendings += $session->read('Transaction.can_signed');
/* /*
class NavHeaderEntry class NavHeaderEntry
@ -23,19 +24,21 @@ class NavHeaderEntry
} }
*/ */
?> ?>
<?php if($errorCount > 0) : ?>
<?= $this->Html->link(
'<i class="material-icons-outlined grd-alert-color">announcement</i>'
. '<span class="notification-indicator notification-indicator-warning">ss</span>',
['controller' => 'StateErrors', 'action' => 'ShowForUser'],
['class' => 'nav-link', 'escape' => false, 'title' => "$errorCount " . __('Fehler')]) ?>
<?php endif; ?>
<?php if($transactionPendings > 0) : ?> <?php if($transactionPendings > 0) : ?>
<a class="notify-link" title="<?= "$transactionPendings " . __('Transaktionen sind noch zu unterzeichnen')?>" href="<?= Router::url('./', true) ?>account/checkTransactions"> <a class="nav-link" title="<?= "$transactionPendings " . __('Transaktionen sind noch zu unterzeichnen')?>" href="<?= Router::url('./', true) ?>account/checkTransactions">
<i class="material-icons-outlined notify">verified_user</i> <i class="material-icons-outlined">verified_user</i>
<!-- <!--
fingerprint fingerprint
today today
--> -->
<!--(<?= $transactionPendings ?>)--> (<?= $transactionPendings ?>)
<!--<span class="notification-indicator notification-indicator-primary">ss</span>-->
</a> </a>
<?php endif; ?> <?php endif; ?>
<?php if($errorCount > 0) : ?>
<?= $this->Html->link(
'<i class="material-icons-outlined notify notify-alert">announcement</i>',
['controller' => 'StateErrors', 'action' => 'ShowForUser'],
['class' => 'notify-link', 'escape' => false, 'title' => "$errorCount " . __('Fehler')]) ?>
<?php endif; ?>