adding first translations, search user now show users

This commit is contained in:
Dario Rekowski on RockPI 2020-01-17 18:59:27 +00:00
parent 82c71a0685
commit 5d3be5dd24
10 changed files with 5246 additions and 155 deletions

View File

@ -2,6 +2,7 @@
namespace App\Controller;
use Cake\Routing\Router;
use Cake\I18n\I18n;
use App\Controller\AppController;
use App\Form\UserSearchForm;
@ -9,6 +10,16 @@ use App\Model\Validation\GenericValidation;
use Model\Transactions\TransactionCreation;
// for translating
__('account created');
__('account not on login-server');
__('email activated');
__('account copied to community');
__('email not activated');
__('account multiple times on login-server');
__('account not on community server');
__('no keys');
/**
* StateUsers Controller
*
@ -36,7 +47,7 @@ class StateUsersController extends AppController
public function index()
{
$this->paginate = [
'contain' => ['Indices', 'StateGroups']
'contain' => []
];
$stateUsers = $this->paginate($this->StateUsers);
@ -55,6 +66,7 @@ class StateUsersController extends AppController
public function search()
{
$startTime = microtime(true);
I18n::setLocale('de_DE');
$this->viewBuilder()->setLayout('frontend_ripple');
$session = $this->getRequest()->getSession();
$result = $this->requestLogin();
@ -82,7 +94,9 @@ class StateUsersController extends AppController
if(GenericValidation::email($searchString, [])) {
$searchType = 'email';
}
// find users on login server
$resultJson = $this->JsonRequestClient->getUsers($session->read('session_id'), $searchString);
$loginServerUser = [];
if($resultJson['state'] == 'success') {
$dataJson = $resultJson['data'];
if($dataJson['state'] != 'success') {
@ -91,13 +105,113 @@ class StateUsersController extends AppController
return $this->redirect(Router::url('/', true) . 'account', 303);
}
}
var_dump($dataJson);
//var_dump($dataJson);
$loginServerUser = $dataJson['users'];
}
$pubkeySorted = [];
$emptyPubkeys = [];
foreach($loginServerUser as $u) {
if(!isset($u['public_hex']) || $u['public_hex'] == '') {
array_push($emptyPubkeys, $u);
} else {
if(!isset($pubkeySorted[$u['public_hex']])) {
$pubkeySorted[$u['public_hex']] = ['login' => [], 'community' => []];
}
array_push($pubkeySorted[$u['public_hex']]['login'], $u);
}
}
// find user on community server db
$globalSearch = '%' . $searchString . '%';
$communityUsers = $this->StateUsers
->find('all')
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]]);
if($searchType != 'email') {
$communityUsers->where(['OR' => [
'first_name LIKE' => $globalSearch,
'last_name LIKE' => $globalSearch
]]);
} else {
$communityUsers->where(['email LIKE' => $globalSearch]);
}
//var_dump($communityUsers->toArray());
foreach($communityUsers as $u) {
$pubkey_hex = bin2hex(stream_get_contents($u->public_key));
$u->public_hex = $pubkey_hex;
if(!isset($pubkeySorted[$pubkey_hex])) {
$pubkeySorted[$pubkey_hex] = ['login' => [], 'community' => []];
}
array_push($pubkeySorted[$u['public_hex']]['community'], $u);
}
$finalUserEntrys = [];
// detect states
foreach($pubkeySorted as $pubhex => $user) {
$finalUser = [];
$state = 'account created';
$color = 'secondary';
$finalUser['balance'] = 0;
$finalUser['pubkeyhex'] = $pubhex;
if(count($user['login']) == 0) {
$state = 'account not on login-server';
$color = 'danger';
if(count($user['community']) == 1) {
$c_user = $user['community'][0];
$finalUser['name'] = $c_user->first_name . ' ' . $c_user->last_name;
$finalUser['email'] = $c_user->email;
}
} else if(count($user['login']) == 1) {
if($user['login'][0]['email_checked'] == true) {
$state = 'email activated';
$color = 'success';
$l_user = $user['login'][0];
$finalUser['name'] = $l_user['first_name'] . ' ' . $l_user['last_name'];
$finalUser['email'] = $l_user['email'];
if(count($user['community']) == 1) {
$state = 'account copied to community';
$color = 'primary';
//var_dump($user['community'][0]->state_balances[0]['amount']);
if(isset($user['community'][0]->state_balances) &&
isset($user['community'][0]->state_balances[0]['amount'])) {
$finalUser['balance'] = $user['community'][0]->state_balances[0]->amount;
}
}
} else {
$state = 'email not activated';
$color = 'warning';
}
} else {
$state = 'account multiple times on login-server';
$color = 'danger';
}
$finalUser['indicator'] = ['name' => $state, 'color' => $color];
array_push($finalUserEntrys, $finalUser);
}
foreach($emptyPubkeys as $user) {
$finalUser = [];
$state = 'account not on community server';
$color = 'secondary';
if($user['email_checked'] == false) {
$state = 'email not activated';
$color = 'warning';
} else {
$state = 'no keys';
$color = 'warning';
}
$finalUser['balance'] = 0;
$finalUser['pubkeyhex'] = '';
$finalUser['name'] = $user['first_name'] . ' ' . $user['last_name'];
$finalUser['email'] = $user['email'];
$finalUser['indicator'] = ['name' => $state, 'color' => $color];
array_push($finalUserEntrys, $finalUser);
}
//var_dump($pubkeySorted);
} else {
$this->Flash->error(__('Something was invalid, please try again!'));
}
$timeUsed = microtime(true) - $startTime;
$this->set('finalUserEntrys', $finalUserEntrys);
$this->set('timeUsed', $timeUsed);
}
}

View File

@ -3,6 +3,9 @@ namespace App\Controller;
use App\Controller\AppController;
use Model\Transactions\Transaction;
use Model\Transactions\TransactionBody;
/**
* Transactions Controller
*
@ -12,6 +15,14 @@ use App\Controller\AppController;
*/
class TransactionsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('GradidoNumber');
$this->Auth->allow(['decode']);
}
/**
* Index method
*
@ -42,6 +53,39 @@ class TransactionsController extends AppController
$this->set('transaction', $transaction);
}
public function decode()
{
$this->viewBuilder()->setLayout('frontend');
if ($this->request->is('post')) {
$base64 = $this->request->getData('base64');
if(!$base64 || $base64 == '') {
$this->Flash->error(__('No valid data given, please try again.'));
} else {
try {
$transactionBin = sodium_base642bin($base64, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
} catch(Exception $ex) {
var_dump($ex);
}
$transaction = new TransactionBody($transactionBin);
if($transaction->hasErrors()) {
$this->set('errors', $transaction->getErrors());
} else {
//$transaction->validate();
if($transaction->hasErrors()) {
$this->set('errors', $transaction->getErrors());
}
//var_dump($transaction);
echo "<br>bin: <br>";
var_dump($transactionBin);
echo "<br>";
$this->set('transaction', $transaction);
}
}
}
}
/**
* Add method

29
src/Locale/cake.pot Normal file
View File

@ -0,0 +1,29 @@
# LANGUAGE translation of CakePHP Application
# Copyright YEAR NAME <EMAIL@ADDRESS>
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2019-11-12 14:40+0000\n"
"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: Template/Error/error400.ctp:36
#: Template/Error/error500.ctp:41
msgid "Error"
msgstr ""
#: Template/Error/error400.ctp:37
msgid "The requested address {0} was not found on this server."
msgstr ""
#: Template/Error/error500.ctp:39
msgid "An Internal Error Has Occurred"
msgstr ""

BIN
src/Locale/de_DE/default.mo Normal file

Binary file not shown.

2223
src/Locale/de_DE/default.po Normal file

File diff suppressed because it is too large Load Diff

2619
src/Locale/default.pot Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,149 +1,159 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
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 $mTransactionBody = null;
public function __construct($base64Data) {
//$transactionBin = base64_decode($base64Data, true);
//if($transactionBin == false)
//sodium_base64_VARIANT_URLSAFE_NO_PADDING
try {
$transactionBin = sodium_base642bin($base64Data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
} catch(\SodiumException $e) {
$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
return;
}
//*/
if($transactionBin == false) {
//$this->addError('base64 decode failed');
$this->addError('Transaction', 'base64 decode error: ' . $base64Data);
} else {
$this->mProtoTransaction = new \Model\Messages\Gradido\Transaction();
try {
$this->mProtoTransaction->mergeFromString($transactionBin);
// cannot catch Exception with cakePHP, I don't know why
} catch(\Google\Protobuf\Internal\GPBDecodeException $e) {
//var_dump($e);
$this->addError('Transaction', $e->getMessage());
return;
}//*/
//echo 'serialize to json: <br>';
//echo $this->mProtoTransaction->serializeToJsonString();
$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() {
$sigMap = $this->mProtoTransaction->getSigMap();
if(!$sigMap) {
$this->addError('Transaction', 'signature map is zero');
return false;
}
//var_dump($sigMap);
//die();
$sigPairs = $sigMap->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('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 save()
{
$connection = ConnectionManager::get('default');
$connection->begin();
//id transaction_id signature pubkey
if (!$this->mTransactionBody->save($this->getFirstPublic(), $this->mProtoTransaction->getSigMap())) {
$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;
}
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
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 $mTransactionBody = null;
public function __construct($base64Data) {
//$transactionBin = base64_decode($base64Data, true);
//if($transactionBin == false) {
//sodium_base64_VARIANT_URLSAFE_NO_PADDING
try {
$transactionBin = sodium_base642bin($base64Data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
} catch(\SodiumException $e) {
//$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
//return;
$transactionBin = base64_decode($base64Data, true);
if($transactionBin == false) {
$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
return;
}
}
//*/}
if($transactionBin == false) {
//$this->addError('base64 decode failed');
$this->addError('Transaction', 'base64 decode error: ' . $base64Data);
} else {
//var_dump($transactionBin);
$this->mProtoTransaction = new \Model\Messages\Gradido\Transaction();
try {
$this->mProtoTransaction->mergeFromString($transactionBin);
var_dump($this->mProtoTransaction);
// cannot catch Exception with cakePHP, I don't know why
} catch(\Google\Protobuf\Internal\GPBDecodeException $e) {
//var_dump($e);
$this->addError('Transaction', $e->getMessage());
return;
}//*/
//echo 'serialize to json: <br>';
//echo $this->mProtoTransaction->serializeToJsonString();
echo "body bytes: <br>";
var_dump($this->mProtoTransaction->getBodyBytes());
echo "<br>end body bytes<br>";
$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() {
$sigMap = $this->mProtoTransaction->getSigMap();
if(!$sigMap) {
$this->addError('Transaction', 'signature map is zero');
return false;
}
//var_dump($sigMap);
//die();
$sigPairs = $sigMap->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('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 save()
{
$connection = ConnectionManager::get('default');
$connection->begin();
//id transaction_id signature pubkey
if (!$this->mTransactionBody->save($this->getFirstPublic(), $this->mProtoTransaction->getSigMap())) {
$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;
}
}

View File

@ -26,8 +26,11 @@
<thead>
<tr>
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
<th scope="col"><?= $this->Paginator->sort('index_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('state_group_id') ?></th>
<!--<th scope="col"><?= $this->Paginator->sort('index_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('state_group_id') ?></th>-->
<th scope="col"><?= $this->Paginator->sort('first_name') ?>
<th scope="col"><?= $this->Paginator->sort('last_name') ?>
<th scope="col"><?= $this->Paginator->sort('email') ?>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
@ -35,8 +38,11 @@
<?php foreach ($stateUsers as $stateUser): ?>
<tr>
<td><?= $this->Number->format($stateUser->id) ?></td>
<td><?= $this->Number->format($stateUser->index_id) ?></td>
<td><?= $stateUser->has('state_group') ? $this->Html->link($stateUser->state_group->name, ['controller' => 'StateGroups', 'action' => 'view', $stateUser->state_group->id]) : '' ?></td>
<!--<td><?= $this->Number->format($stateUser->index_id) ?></td>
<td><?= $stateUser->has('state_group') ? $this->Html->link($stateUser->state_group->name, ['controller' => 'StateGroups', 'action' => 'view', $stateUser->state_group->id]) : '' ?></td>-->
<td><?= $stateUser->first_name ?></td>
<td><?= $stateUser->last_name ?></td>
<td><?= $stateUser->email ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $stateUser->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $stateUser->id]) ?>

View File

@ -30,3 +30,48 @@ $this->loadHelper('Form', [
</div>
</div>
</div>
<div class="row">
<div class="col-md-10 equel-grid">
<div class="grid">
<?php if(count($finalUserEntrys) > 0) : ?>
<div class="grid-body py-3">
<p class="grid-header"><?= __('Benutzer gefunden') ?></p>
</div>
<div class="table-responsive">
<table class="table table-hover table-sm">
<thead>
<tr class="solid-header">
<th class="pl-4">Name</th>
<th>E-Mail</th>
<th>Kontostand</th>
<th>Public Key</th>
</tr>
</thead>
<tbody>
<?php foreach($finalUserEntrys as $user) : ?>
<tr>
<td class="pr-0 pl-4">
<span class="text-black font-weight-medium d-block">
<?= $user['name'] ?>
</span>
<span>
<span class="status-indicator rounded-indicator small bg-<?= $user['indicator']['color'] ?>"></span>
<small><?= __($user['indicator']['name']) ?></small>
</span>
</td>
<td><?= $user['email'] ?></td>
<td><?= $this->element('printGradido', ['number' => $user['balance']]) ?></td>
<td title="<?= $user['pubkeyhex'] ?>"><?= substr($user['pubkeyhex'], 0, 10) . '...' ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else : ?>
<div class="grid-body py-3">
<p class="grid-header"><?= __('Keine Benutzer gefunden') ?></p>
</div>
<?php endif; ?>
</div>
</div>
</div>

View File

@ -35,7 +35,8 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
'validCreation900' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQNVZ8Ae3Zbg3G0wZ840fzKan6N4KtTcSe0KYi17kQwFmsl18oFxXv8_s6j1xXFrIKjy1_1Olq0a7xYLErDMkjwYqORIGCNb5iu4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgNHKCBC1ie2WCg',
'validCreation1200' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQEEey5QMAdldoOTP_jTETHgOQriGsixEY0cziQeRfT_J5YtbI_A6AizEYD-JcxmRmXzv1xjjTgsV39Y32ta2CQkqORIGCIeGi-4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgOy4CxC1ie2WCg',
'notBase64' => 'CgpIYWxsbyBXZW-0EgYIyfSG7gV_LwonCiCboKikqwjZfes9xuqgthFH3',
'validTransfer' => 'GmYKZAoggZC9pYXuXx2fv30G6B5p7BjhM3YQTP9Ut0V-t9PvcQ0SQDddHyKzAX3LBV0PuDiPc6lxkUipss5tyuLRpMtFJQnT30tsbYIkA1FXimjMKOoiuLswf4OLLV3bAIYehW-b9AgqYQoFSGFsbG8SBgiJlaPvBUJQCiYKIIGQvaWF7l8dn799BugeaewY4TN2EEz_VLdFfrfT73ENEICfSRImCiDtdleSLxhUgEbMW9DpqIwsykFj3-z_enKEOuGnXrmW8xCAn0k'
'validTransfer' => 'GmYKZAoggZC9pYXuXx2fv30G6B5p7BjhM3YQTP9Ut0V-t9PvcQ0SQDddHyKzAX3LBV0PuDiPc6lxkUipss5tyuLRpMtFJQnT30tsbYIkA1FXimjMKOoiuLswf4OLLV3bAIYehW-b9AgqYQoFSGFsbG8SBgiJlaPvBUJQCiYKIIGQvaWF7l8dn799BugeaewY4TN2EEz_VLdFfrfT73ENEICfSRImCiDtdleSLxhUgEbMW9DpqIwsykFj3-z_enKEOuGnXrmW8xCAn0k',
'errornusTransfer' => 'ClxGcm9oZXMgTmV1ZXMgSmFociB1bmQgREFOS0UsIGRhc3MgZHUgZGljaCBzbyBlaW5zZXR6dCBmw7xyIEdyYWRpZG8hIEhlcnpsaWNoZSBHcsO8w59lIFRlcmVzYRIGCPjjgvEFQlAKJgogUQwFYeVlGlfWDrkXNN7rHwejoCDJKt+YkYJfbJVyj3EQwIQ9EiYKIPXIRnUhVJ/zCs5+y/VaTBjTIoYizJNwS+JC//xsbQrHEMCEPQ=='
];
/*public function setUp() {