replace \r\n with \n

This commit is contained in:
einhornimmond 2021-03-31 17:08:37 +02:00
parent 9946cc0e13
commit 55334799cb
31 changed files with 2957 additions and 2957 deletions

View File

@ -1,83 +1,83 @@
<?php <?php
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
namespace App\Controller\Component; namespace App\Controller\Component;
use Cake\Controller\Component; use Cake\Controller\Component;
use Cake\Http\Client; use Cake\Http\Client;
use Cake\Core\Configure; use Cake\Core\Configure;
use Datto\JsonRpc\Client as JsonRpcClient; use Datto\JsonRpc\Client as JsonRpcClient;
//App\Controller\Component\ComponentRegistry //App\Controller\Component\ComponentRegistry
class JsonRpcRequestClientComponent extends Component class JsonRpcRequestClientComponent extends Component
{ {
var $rpcClient = null; var $rpcClient = null;
public function __construct($registry, array $config = array()) { public function __construct($registry, array $config = array()) {
parent::__construct($registry, $config); parent::__construct($registry, $config);
$this->rpcClient = new JsonRpcClient(); $this->rpcClient = new JsonRpcClient();
} }
// @param id: if id = 0 call rand for it // @param id: if id = 0 call rand for it
public function request($method, $params = [], $id = 0) public function request($method, $params = [], $id = 0)
{ {
if(0 == $id) { if(0 == $id) {
$id = random_int(1, 12000); $id = random_int(1, 12000);
} }
$this->rpcClient->query($id, $method, $params); $this->rpcClient->query($id, $method, $params);
$message = $this->rpcClient->encode(); $message = $this->rpcClient->encode();
return $this->sendRequest($message); return $this->sendRequest($message);
// message: {"jsonrpc":"2.0","method":"add","params":[1,2],"id":1} // message: {"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}
} }
public function sendRequest($message) { public function sendRequest($message) {
$http = new Client(); $http = new Client();
try { try {
$url = $this->pickGradidoNodeUrl(); $url = $this->pickGradidoNodeUrl();
if(is_array($url)) { if(is_array($url)) {
return $url; return $url;
} }
$response = $http->post($url, $message, ['type' => 'json']); $response = $http->post($url, $message, ['type' => 'json']);
} catch(Exception $e) { } catch(Exception $e) {
return ['state' => 'error', 'type' => 'http exception', 'details' => $e->getMessage()]; return ['state' => 'error', 'type' => 'http exception', 'details' => $e->getMessage()];
} }
$responseStatus = $response->getStatusCode(); $responseStatus = $response->getStatusCode();
if($responseStatus != 200) { if($responseStatus != 200) {
return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response status code isn\'t 200', 'details' => $responseStatus]; return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response status code isn\'t 200', 'details' => $responseStatus];
} }
//$responseType = $response->getType(); //$responseType = $response->getType();
//if($responseType != 'application/json') { //if($responseType != 'application/json') {
// return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t json', 'details' => $responseType]; // return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t json', 'details' => $responseType];
// } // }
$json = $response->getJson(); $json = $response->getJson();
if($json == null) { if($json == null) {
//$responseType = $response->getType(); //$responseType = $response->getType();
return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json']; return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json'];
} }
return $json['result']; return $json['result'];
//return ['state' => 'success', 'data' => $json]; //return ['state' => 'success', 'data' => $json];
} }
static public function pickGradidoNodeUrl() static public function pickGradidoNodeUrl()
{ {
$gradidoNodes = Configure::read('GradidoNode'); $gradidoNodes = Configure::read('GradidoNode');
if(count($gradidoNodes) == 0) { if(count($gradidoNodes) == 0) {
return ['state' => 'error', 'msg' => 'no gradido nodes in config']; return ['state' => 'error', 'msg' => 'no gradido nodes in config'];
} }
$i = rand(0, count($gradidoNodes)-1); $i = rand(0, count($gradidoNodes)-1);
return $gradidoNodes[$i]['host'] . ':' . $gradidoNodes[$i]['port']; return $gradidoNodes[$i]['host'] . ':' . $gradidoNodes[$i]['port'];
} }
} }

View File

@ -22,9 +22,9 @@ class Key extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type string $ed25519 * @type string $ed25519
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* @type string $ed25519_ref10 * @type string $ed25519_ref10
* ed25519 ref10 signature * ed25519 ref10 signature
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -33,7 +33,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @return string * @return string
@ -44,7 +44,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @param string $var * @param string $var
@ -59,7 +59,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @return string * @return string
@ -70,7 +70,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @param string $var * @param string $var

View File

@ -22,7 +22,7 @@ class SenderAmount extends \Google\Protobuf\Internal\Message
*/ */
private $amount = 0; private $amount = 0;
/** /**
* sender balance after transaction, including perishability * sender balance after transaction, including perishability
* *
* Generated from protobuf field <code>sint64 senderFinalBalance = 3;</code> * Generated from protobuf field <code>sint64 senderFinalBalance = 3;</code>
*/ */
@ -37,7 +37,7 @@ class SenderAmount extends \Google\Protobuf\Internal\Message
* @type string $ed25519_sender_pubkey * @type string $ed25519_sender_pubkey
* @type int|string $amount * @type int|string $amount
* @type int|string $senderFinalBalance * @type int|string $senderFinalBalance
* sender balance after transaction, including perishability * sender balance after transaction, including perishability
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -90,7 +90,7 @@ class SenderAmount extends \Google\Protobuf\Internal\Message
} }
/** /**
* sender balance after transaction, including perishability * sender balance after transaction, including perishability
* *
* Generated from protobuf field <code>sint64 senderFinalBalance = 3;</code> * Generated from protobuf field <code>sint64 senderFinalBalance = 3;</code>
* @return int|string * @return int|string
@ -101,7 +101,7 @@ class SenderAmount extends \Google\Protobuf\Internal\Message
} }
/** /**
* sender balance after transaction, including perishability * sender balance after transaction, including perishability
* *
* Generated from protobuf field <code>sint64 senderFinalBalance = 3;</code> * Generated from protobuf field <code>sint64 senderFinalBalance = 3;</code>
* @param int|string $var * @param int|string $var

View File

@ -14,7 +14,7 @@ use Google\Protobuf\Internal\GPBUtil;
class SignatureMap extends \Google\Protobuf\Internal\Message class SignatureMap extends \Google\Protobuf\Internal\Message
{ {
/** /**
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* *
* Generated from protobuf field <code>repeated .model.messages.gradido.SignaturePair sigPair = 1;</code> * Generated from protobuf field <code>repeated .model.messages.gradido.SignaturePair sigPair = 1;</code>
*/ */
@ -27,7 +27,7 @@ class SignatureMap extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type \Model\Messages\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $sigPair * @type \Model\Messages\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $sigPair
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -36,7 +36,7 @@ class SignatureMap extends \Google\Protobuf\Internal\Message
} }
/** /**
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* *
* Generated from protobuf field <code>repeated .model.messages.gradido.SignaturePair sigPair = 1;</code> * Generated from protobuf field <code>repeated .model.messages.gradido.SignaturePair sigPair = 1;</code>
* @return \Google\Protobuf\Internal\RepeatedField * @return \Google\Protobuf\Internal\RepeatedField
@ -47,7 +47,7 @@ class SignatureMap extends \Google\Protobuf\Internal\Message
} }
/** /**
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* *
* Generated from protobuf field <code>repeated .model.messages.gradido.SignaturePair sigPair = 1;</code> * Generated from protobuf field <code>repeated .model.messages.gradido.SignaturePair sigPair = 1;</code>
* @param \Model\Messages\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $var * @param \Model\Messages\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $var

View File

@ -27,9 +27,9 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
* *
* @type string $pubKey * @type string $pubKey
* @type string $ed25519 * @type string $ed25519
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* @type string $ed25519_ref10 * @type string $ed25519_ref10
* ed25519 ref10 signature * ed25519 ref10 signature
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -60,7 +60,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @return string * @return string
@ -71,7 +71,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @param string $var * @param string $var
@ -86,7 +86,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @return string * @return string
@ -97,7 +97,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @param string $var * @param string $var

View File

@ -9,7 +9,7 @@ use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil; use Google\Protobuf\Internal\GPBUtil;
/** /**
* need signature from this group and from parent (if it isn't zero) * need signature from this group and from parent (if it isn't zero)
* *
* Generated from protobuf message <code>model.messages.gradido.StateCreateGroup</code> * Generated from protobuf message <code>model.messages.gradido.StateCreateGroup</code>
*/ */

View File

@ -9,7 +9,7 @@ use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil; use Google\Protobuf\Internal\GPBUtil;
/** /**
* need signature from this group and from both parents (if it isn't zero) * need signature from this group and from both parents (if it isn't zero)
* *
* Generated from protobuf message <code>model.messages.gradido.StateGroupChangeParent</code> * Generated from protobuf message <code>model.messages.gradido.StateGroupChangeParent</code>
*/ */

View File

@ -16,13 +16,13 @@ use Google\Protobuf\Internal\GPBUtil;
class Timestamp extends \Google\Protobuf\Internal\Message class Timestamp extends \Google\Protobuf\Internal\Message
{ {
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
*/ */
private $seconds = 0; private $seconds = 0;
/** /**
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* *
* Generated from protobuf field <code>int32 nanos = 2;</code> * Generated from protobuf field <code>int32 nanos = 2;</code>
*/ */
@ -35,9 +35,9 @@ class Timestamp extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type int|string $seconds * @type int|string $seconds
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* @type int $nanos * @type int $nanos
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -46,7 +46,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @return int|string * @return int|string
@ -57,7 +57,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @param int|string $var * @param int|string $var
@ -72,7 +72,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* *
* Generated from protobuf field <code>int32 nanos = 2;</code> * Generated from protobuf field <code>int32 nanos = 2;</code>
* @return int * @return int
@ -83,7 +83,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* *
* Generated from protobuf field <code>int32 nanos = 2;</code> * Generated from protobuf field <code>int32 nanos = 2;</code>
* @param int $var * @param int $var

View File

@ -16,7 +16,7 @@ use Google\Protobuf\Internal\GPBUtil;
class TimestampSeconds extends \Google\Protobuf\Internal\Message class TimestampSeconds extends \Google\Protobuf\Internal\Message
{ {
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
*/ */
@ -29,7 +29,7 @@ class TimestampSeconds extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type int|string $seconds * @type int|string $seconds
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -38,7 +38,7 @@ class TimestampSeconds extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @return int|string * @return int|string
@ -49,7 +49,7 @@ class TimestampSeconds extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @param int|string $var * @param int|string $var

View File

@ -9,27 +9,27 @@ use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil; use Google\Protobuf\Internal\GPBUtil;
/** /**
* need signature from group admin or * need signature from group admin or
* percent of group users another than the receiver * percent of group users another than the receiver
* *
* Generated from protobuf message <code>model.messages.gradido.TransactionCreation</code> * Generated from protobuf message <code>model.messages.gradido.TransactionCreation</code>
*/ */
class TransactionCreation extends \Google\Protobuf\Internal\Message class TransactionCreation extends \Google\Protobuf\Internal\Message
{ {
/** /**
* 40 Byte * 40 Byte
* *
* Generated from protobuf field <code>.model.messages.gradido.ReceiverAmount receiverAmount = 1;</code> * Generated from protobuf field <code>.model.messages.gradido.ReceiverAmount receiverAmount = 1;</code>
*/ */
private $receiverAmount = null; private $receiverAmount = null;
/** /**
* 4 Byte * 4 Byte
* *
* Generated from protobuf field <code>sint32 ident_hash = 2;</code> * Generated from protobuf field <code>sint32 ident_hash = 2;</code>
*/ */
private $ident_hash = 0; private $ident_hash = 0;
/** /**
* 8 Byte * 8 Byte
* *
* Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds target_date = 3;</code> * Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds target_date = 3;</code>
*/ */
@ -42,11 +42,11 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type \Model\Messages\Gradido\ReceiverAmount $receiverAmount * @type \Model\Messages\Gradido\ReceiverAmount $receiverAmount
* 40 Byte * 40 Byte
* @type int $ident_hash * @type int $ident_hash
* 4 Byte * 4 Byte
* @type \Model\Messages\Gradido\TimestampSeconds $target_date * @type \Model\Messages\Gradido\TimestampSeconds $target_date
* 8 Byte * 8 Byte
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -55,7 +55,7 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
} }
/** /**
* 40 Byte * 40 Byte
* *
* Generated from protobuf field <code>.model.messages.gradido.ReceiverAmount receiverAmount = 1;</code> * Generated from protobuf field <code>.model.messages.gradido.ReceiverAmount receiverAmount = 1;</code>
* @return \Model\Messages\Gradido\ReceiverAmount * @return \Model\Messages\Gradido\ReceiverAmount
@ -66,7 +66,7 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
} }
/** /**
* 40 Byte * 40 Byte
* *
* Generated from protobuf field <code>.model.messages.gradido.ReceiverAmount receiverAmount = 1;</code> * Generated from protobuf field <code>.model.messages.gradido.ReceiverAmount receiverAmount = 1;</code>
* @param \Model\Messages\Gradido\ReceiverAmount $var * @param \Model\Messages\Gradido\ReceiverAmount $var
@ -81,7 +81,7 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
} }
/** /**
* 4 Byte * 4 Byte
* *
* Generated from protobuf field <code>sint32 ident_hash = 2;</code> * Generated from protobuf field <code>sint32 ident_hash = 2;</code>
* @return int * @return int
@ -92,7 +92,7 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
} }
/** /**
* 4 Byte * 4 Byte
* *
* Generated from protobuf field <code>sint32 ident_hash = 2;</code> * Generated from protobuf field <code>sint32 ident_hash = 2;</code>
* @param int $var * @param int $var
@ -107,7 +107,7 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
} }
/** /**
* 8 Byte * 8 Byte
* *
* Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds target_date = 3;</code> * Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds target_date = 3;</code>
* @return \Model\Messages\Gradido\TimestampSeconds * @return \Model\Messages\Gradido\TimestampSeconds
@ -118,7 +118,7 @@ class TransactionCreation extends \Google\Protobuf\Internal\Message
} }
/** /**
* 8 Byte * 8 Byte
* *
* Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds target_date = 3;</code> * Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds target_date = 3;</code>
* @param \Model\Messages\Gradido\TimestampSeconds $var * @param \Model\Messages\Gradido\TimestampSeconds $var

View File

@ -22,9 +22,9 @@ class Key extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type string $ed25519 * @type string $ed25519
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* @type string $ed25519_ref10 * @type string $ed25519_ref10
* ed25519 ref10 signature * ed25519 ref10 signature
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -33,7 +33,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @return string * @return string
@ -44,7 +44,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @param string $var * @param string $var
@ -59,7 +59,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @return string * @return string
@ -70,7 +70,7 @@ class Key extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @param string $var * @param string $var

View File

@ -14,7 +14,7 @@ use Google\Protobuf\Internal\GPBUtil;
class SignatureMap extends \Google\Protobuf\Internal\Message class SignatureMap extends \Google\Protobuf\Internal\Message
{ {
/** /**
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* *
* Generated from protobuf field <code>repeated .proto.gradido.SignaturePair sigPair = 1;</code> * Generated from protobuf field <code>repeated .proto.gradido.SignaturePair sigPair = 1;</code>
*/ */
@ -27,7 +27,7 @@ class SignatureMap extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type \Proto\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $sigPair * @type \Proto\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $sigPair
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -36,7 +36,7 @@ class SignatureMap extends \Google\Protobuf\Internal\Message
} }
/** /**
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* *
* Generated from protobuf field <code>repeated .proto.gradido.SignaturePair sigPair = 1;</code> * Generated from protobuf field <code>repeated .proto.gradido.SignaturePair sigPair = 1;</code>
* @return \Google\Protobuf\Internal\RepeatedField * @return \Google\Protobuf\Internal\RepeatedField
@ -47,7 +47,7 @@ class SignatureMap extends \Google\Protobuf\Internal\Message
} }
/** /**
* Each signature pair corresponds to a unique Key required to sign the transaction. * Each signature pair corresponds to a unique Key required to sign the transaction.
* *
* Generated from protobuf field <code>repeated .proto.gradido.SignaturePair sigPair = 1;</code> * Generated from protobuf field <code>repeated .proto.gradido.SignaturePair sigPair = 1;</code>
* @param \Proto\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $var * @param \Proto\Gradido\SignaturePair[]|\Google\Protobuf\Internal\RepeatedField $var

View File

@ -27,9 +27,9 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
* *
* @type string $pubKey * @type string $pubKey
* @type string $ed25519 * @type string $ed25519
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* @type string $ed25519_ref10 * @type string $ed25519_ref10
* ed25519 ref10 signature * ed25519 ref10 signature
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -60,7 +60,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @return string * @return string
@ -71,7 +71,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 signature (libsodium default) * ed25519 signature (libsodium default)
* *
* Generated from protobuf field <code>bytes ed25519 = 2;</code> * Generated from protobuf field <code>bytes ed25519 = 2;</code>
* @param string $var * @param string $var
@ -86,7 +86,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @return string * @return string
@ -97,7 +97,7 @@ class SignaturePair extends \Google\Protobuf\Internal\Message
} }
/** /**
* ed25519 ref10 signature * ed25519 ref10 signature
* *
* Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code> * Generated from protobuf field <code>bytes ed25519_ref10 = 3;</code>
* @param string $var * @param string $var

View File

@ -16,13 +16,13 @@ use Google\Protobuf\Internal\GPBUtil;
class Timestamp extends \Google\Protobuf\Internal\Message class Timestamp extends \Google\Protobuf\Internal\Message
{ {
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
*/ */
private $seconds = 0; private $seconds = 0;
/** /**
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* *
* Generated from protobuf field <code>int32 nanos = 2;</code> * Generated from protobuf field <code>int32 nanos = 2;</code>
*/ */
@ -35,9 +35,9 @@ class Timestamp extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type int|string $seconds * @type int|string $seconds
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* @type int $nanos * @type int $nanos
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -46,7 +46,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @return int|string * @return int|string
@ -57,7 +57,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @param int|string $var * @param int|string $var
@ -72,7 +72,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* *
* Generated from protobuf field <code>int32 nanos = 2;</code> * Generated from protobuf field <code>int32 nanos = 2;</code>
* @return int * @return int
@ -83,7 +83,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of nanoseconds since the start of the last second * Number of nanoseconds since the start of the last second
* *
* Generated from protobuf field <code>int32 nanos = 2;</code> * Generated from protobuf field <code>int32 nanos = 2;</code>
* @param int $var * @param int $var

View File

@ -16,7 +16,7 @@ use Google\Protobuf\Internal\GPBUtil;
class TimestampSeconds extends \Google\Protobuf\Internal\Message class TimestampSeconds extends \Google\Protobuf\Internal\Message
{ {
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
*/ */
@ -29,7 +29,7 @@ class TimestampSeconds extends \Google\Protobuf\Internal\Message
* Optional. Data for populating the Message object. * Optional. Data for populating the Message object.
* *
* @type int|string $seconds * @type int|string $seconds
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* } * }
*/ */
public function __construct($data = NULL) { public function __construct($data = NULL) {
@ -38,7 +38,7 @@ class TimestampSeconds extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @return int|string * @return int|string
@ -49,7 +49,7 @@ class TimestampSeconds extends \Google\Protobuf\Internal\Message
} }
/** /**
* Number of complete seconds since the start of the epoch * Number of complete seconds since the start of the epoch
* *
* Generated from protobuf field <code>int64 seconds = 1;</code> * Generated from protobuf field <code>int64 seconds = 1;</code>
* @param int|string $var * @param int|string $var

File diff suppressed because it is too large Load Diff

View File

@ -1,269 +1,269 @@
<?php <?php
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
namespace Model\Transactions; namespace Model\Transactions;
//use Model\Messages\Gradido\Transaction; //use Model\Messages\Gradido\Transaction;
//use Model\Messages\Gradido\TransactionBody; //use Model\Messages\Gradido\TransactionBody;
use Cake\ORM\TableRegistry; use Cake\ORM\TableRegistry;
use Cake\Datasource\ConnectionManager; use Cake\Datasource\ConnectionManager;
class Transaction extends TransactionBase { class Transaction extends TransactionBase {
private $mProtoTransaction = null; private $mProtoTransaction = null;
private $mTransactionBody = null; private $mTransactionBody = null;
public function __construct($base64Data) public function __construct($base64Data)
{ {
//$transactionBin = base64_decode($base64Data, true); //$transactionBin = base64_decode($base64Data, true);
//if($transactionBin == false) { //if($transactionBin == false) {
//sodium_base64_VARIANT_URLSAFE_NO_PADDING //sodium_base64_VARIANT_URLSAFE_NO_PADDING
if(is_a($base64Data, '\Model\Messages\Gradido\Transaction')) { if(is_a($base64Data, '\Model\Messages\Gradido\Transaction')) {
$this->mProtoTransaction = $base64Data; $this->mProtoTransaction = $base64Data;
$this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes()); $this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes());
return; return;
} }
try { try {
$transactionBin = sodium_base642bin($base64Data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING); $transactionBin = sodium_base642bin($base64Data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
} catch(\SodiumException $e) { } catch(\SodiumException $e) {
//$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data); //$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
//return; //return;
$transactionBin = base64_decode($base64Data, true); $transactionBin = base64_decode($base64Data, true);
if($transactionBin == false) { if($transactionBin == false) {
$this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data); $this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
return; return;
} }
} }
//*/} //*/}
if($transactionBin == false) { if($transactionBin == false) {
//$this->addError('base64 decode failed'); //$this->addError('base64 decode failed');
$this->addError('Transaction', 'base64 decode error: ' . $base64Data); $this->addError('Transaction', 'base64 decode error: ' . $base64Data);
} else { } else {
//var_dump($transactionBin); //var_dump($transactionBin);
$this->mProtoTransaction = new \Model\Messages\Gradido\Transaction(); $this->mProtoTransaction = new \Model\Messages\Gradido\Transaction();
try { try {
$this->mProtoTransaction->mergeFromString($transactionBin); $this->mProtoTransaction->mergeFromString($transactionBin);
//var_dump($this->mProtoTransaction); //var_dump($this->mProtoTransaction);
// cannot catch Exception with cakePHP, I don't know why // cannot catch Exception with cakePHP, I don't know why
} catch(\Google\Protobuf\Internal\GPBDecodeException $e) { } catch(\Google\Protobuf\Internal\GPBDecodeException $e) {
//var_dump($e); //var_dump($e);
$this->addError('Transaction', $e->getMessage()); $this->addError('Transaction', $e->getMessage());
return; return;
}//*/ }//*/
//echo 'serialize to json: <br>'; //echo 'serialize to json: <br>';
//echo $this->mProtoTransaction->serializeToJsonString(); //echo $this->mProtoTransaction->serializeToJsonString();
//echo "body bytes: <br>"; //echo "body bytes: <br>";
//var_dump($this->mProtoTransaction->getBodyBytes()); //var_dump($this->mProtoTransaction->getBodyBytes());
//echo "<br>end body bytes<br>"; //echo "<br>end body bytes<br>";
$this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes()); $this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes());
} }
} }
static public function build(\Model\Messages\Gradido\TransactionBody $transactionBody, $senderKeyPair) static public function build(\Model\Messages\Gradido\TransactionBody $transactionBody, $senderKeyPair)
{ {
$protoTransaction = new \Model\Messages\Gradido\Transaction(); $protoTransaction = new \Model\Messages\Gradido\Transaction();
$recevied = new \Model\Messages\Gradido\TimestampSeconds(); $recevied = new \Model\Messages\Gradido\TimestampSeconds();
$recevied->setSeconds(time()); $recevied->setSeconds(time());
$protoTransaction->setReceived($recevied); $protoTransaction->setReceived($recevied);
$bodyBytes = $transactionBody->serializeToString(); $bodyBytes = $transactionBody->serializeToString();
$sigMap = SignatureMap::build($bodyBytes, [$senderKeyPair]); $sigMap = SignatureMap::build($bodyBytes, [$senderKeyPair]);
$protoTransaction->setSigMap($sigMap->getProto()); $protoTransaction->setSigMap($sigMap->getProto());
$protoTransaction->setBodyBytes($bodyBytes); $protoTransaction->setBodyBytes($bodyBytes);
return $protoTransaction; return $protoTransaction;
} }
public function getTransactionBody() { public function getTransactionBody() {
return $this->mTransactionBody; return $this->mTransactionBody;
} }
public function getFirstPublic() { public function getFirstPublic() {
$sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair(); $sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
return $sigPairs[0]->getPubKey(); return $sigPairs[0]->getPubKey();
} }
public function getId() { public function getId() {
return $this->mProtoTransaction->getId(); return $this->mProtoTransaction->getId();
} }
public function validate() { public function validate() {
$sigMap = $this->mProtoTransaction->getSigMap(); $sigMap = $this->mProtoTransaction->getSigMap();
if(!$sigMap) { if(!$sigMap) {
$this->addError('Transaction', 'signature map is zero'); $this->addError('Transaction', 'signature map is zero');
return false; return false;
} }
//var_dump($sigMap); //var_dump($sigMap);
//die(); //die();
$sigPairs = $sigMap->getSigPair(); $sigPairs = $sigMap->getSigPair();
$bodyBytes = $this->mProtoTransaction->getBodyBytes(); $bodyBytes = $this->mProtoTransaction->getBodyBytes();
if(!$sigPairs || count($sigPairs) < 1) { if(!$sigPairs || count($sigPairs) < 1) {
$this->addError('Transaction::validate', 'no signature found'); $this->addError('Transaction::validate', 'no signature found');
return false; return false;
} }
// check signature(s) // check signature(s)
foreach($sigPairs as $sigPair) { foreach($sigPairs as $sigPair) {
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>"; //echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
$pubkey = $sigPair->getPubKey(); $pubkey = $sigPair->getPubKey();
$signature = $sigPair->getEd25519(); $signature = $sigPair->getEd25519();
//echo "verify bodybytes: <br>" . bin2hex($bodyBytes) . '<br>'; //echo "verify bodybytes: <br>" . bin2hex($bodyBytes) . '<br>';
if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) { if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
$this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' ); $this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
return false; return false;
} }
} }
if(!$this->mTransactionBody->validate($sigPairs)) { if(!$this->mTransactionBody->validate($sigPairs)) {
$this->addErrors($this->mTransactionBody->getErrors()); $this->addErrors($this->mTransactionBody->getErrors());
return false; return false;
} }
return true; return true;
} }
public function save() public function save()
{ {
$connection = ConnectionManager::get('default'); $connection = ConnectionManager::get('default');
$connection->begin(); $connection->begin();
//id transaction_id signature pubkey //id transaction_id signature pubkey
if (!$this->mTransactionBody->save($this->getFirstPublic(), $this->mProtoTransaction->getSigMap())) { if (!$this->mTransactionBody->save($this->getFirstPublic(), $this->mProtoTransaction->getSigMap())) {
$this->addErrors($this->mTransactionBody->getErrors()); $this->addErrors($this->mTransactionBody->getErrors());
$connection->rollback(); $connection->rollback();
return false; return false;
} }
// save transaction signatures // save transaction signatures
$transactionsSignaturesTable = TableRegistry::getTableLocator()->get('transaction_signatures'); $transactionsSignaturesTable = TableRegistry::getTableLocator()->get('transaction_signatures');
$transactionId = $this->mTransactionBody->getTransactionID(); $transactionId = $this->mTransactionBody->getTransactionID();
//signature pubkey //signature pubkey
$sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair(); $sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
//echo "sigPairs: "; var_dump($sigPairs); //echo "sigPairs: "; var_dump($sigPairs);
$signatureEntitys = []; $signatureEntitys = [];
foreach($sigPairs as $sigPair) { foreach($sigPairs as $sigPair) {
$signatureEntity = $transactionsSignaturesTable->newEntity(); $signatureEntity = $transactionsSignaturesTable->newEntity();
$signatureEntity->transaction_id = $transactionId; $signatureEntity->transaction_id = $transactionId;
$signatureEntity->signature = $sigPair->getEd25519(); $signatureEntity->signature = $sigPair->getEd25519();
$signatureEntity->pubkey = $sigPair->getPubKey(); $signatureEntity->pubkey = $sigPair->getPubKey();
array_push($signatureEntitys, $signatureEntity); array_push($signatureEntitys, $signatureEntity);
} }
//debug($signatureEntitys); //debug($signatureEntitys);
if(!$transactionsSignaturesTable->saveMany($signatureEntitys)) { if(!$transactionsSignaturesTable->saveMany($signatureEntitys)) {
foreach($signatureEntitys as $entity) { foreach($signatureEntitys as $entity) {
$errors = $entity->getErrors(); $errors = $entity->getErrors();
if(!$errors && count($errors) > 0) { if(!$errors && count($errors) > 0) {
$pubkeyHex = bin2hex($entity->pubkey); $pubkeyHex = bin2hex($entity->pubkey);
$this->addError('Transaction::save', 'error saving signature for pubkey: ' . $pubkeyHex . ', with errors: ' . json_encode($errors) ); $this->addError('Transaction::save', 'error saving signature for pubkey: ' . $pubkeyHex . ', with errors: ' . json_encode($errors) );
} }
} }
$connection->rollback(); $connection->rollback();
return false; return false;
} }
$connection->commit(); $connection->commit();
$this->mTransactionBody->getSpecificTransaction()->sendNotificationEmail($this->mTransactionBody->getMemo()); $this->mTransactionBody->getSpecificTransaction()->sendNotificationEmail($this->mTransactionBody->getMemo());
return true; return true;
} }
static public function fromTable($id) static public function fromTable($id)
{ {
$transactionsTable = TableRegistry::getTableLocator()->get('transactions'); $transactionsTable = TableRegistry::getTableLocator()->get('transactions');
$transactionEntry = $transactionsTable $transactionEntry = $transactionsTable
->find('all') ->find('all')
->where(['id' => $id]) ->where(['id' => $id])
->contain([ ->contain([
'TransactionCreations', 'TransactionCreations',
'TransactionSendCoins', 'TransactionSendCoins',
'TransactionSignatures']) 'TransactionSignatures'])
->first(); ->first();
//var_dump($transactionEntry->toArray()); //var_dump($transactionEntry->toArray());
$protoTransaction = new \Model\Messages\Gradido\Transaction(); $protoTransaction = new \Model\Messages\Gradido\Transaction();
$protoTransaction->setId($transactionEntry->id); $protoTransaction->setId($transactionEntry->id);
$recevied = new \Model\Messages\Gradido\TimestampSeconds(); $recevied = new \Model\Messages\Gradido\TimestampSeconds();
$recevied->setSeconds($transactionEntry->received->getTimestamp()); $recevied->setSeconds($transactionEntry->received->getTimestamp());
$protoTransaction->setReceived($recevied); $protoTransaction->setReceived($recevied);
$sigMap = SignatureMap::fromEntity($transactionEntry->transaction_signatures); $sigMap = SignatureMap::fromEntity($transactionEntry->transaction_signatures);
$protoTransaction->setSigMap($sigMap->getProto()); $protoTransaction->setSigMap($sigMap->getProto());
//echo "sig map: check<br>"; //echo "sig map: check<br>";
$protoTransaction->setTxHash(stream_get_contents($transactionEntry->tx_hash)); $protoTransaction->setTxHash(stream_get_contents($transactionEntry->tx_hash));
$body = TransactionBody::fromEntity($transactionEntry->memo, $transactionEntry); $body = TransactionBody::fromEntity($transactionEntry->memo, $transactionEntry);
if(is_array($body)) { if(is_array($body)) {
return ['state' => 'error', 'msg' => 'error creating body transaction', 'details' => $body]; return ['state' => 'error', 'msg' => 'error creating body transaction', 'details' => $body];
} }
// validate signatures // validate signatures
$sigPairs = $sigMap->getProto()->getSigPair(); $sigPairs = $sigMap->getProto()->getSigPair();
if(!$sigPairs || count($sigPairs) < 1) { if(!$sigPairs || count($sigPairs) < 1) {
return ['state' => 'error', 'msg' => 'error no signatures found']; return ['state' => 'error', 'msg' => 'error no signatures found'];
} }
//echo "verify bodybytes: <br>" . bin2hex($bodyBytes) . '<br>'; //echo "verify bodybytes: <br>" . bin2hex($bodyBytes) . '<br>';
$created = new \Model\Messages\Gradido\TimestampSeconds(); $created = new \Model\Messages\Gradido\TimestampSeconds();
$created->setSeconds($recevied->getSeconds()); $created->setSeconds($recevied->getSeconds());
$body->setCreated($created); $body->setCreated($created);
$bodyBytes = $body->serializeToString(); $bodyBytes = $body->serializeToString();
$createTrys = 0; $createTrys = 0;
$createRight = false; $createRight = false;
// check signature(s) and // check signature(s) and
// try to get created field of TransactionBody right, because it wasn't saved // try to get created field of TransactionBody right, because it wasn't saved
foreach($sigPairs as $sigPair) { foreach($sigPairs as $sigPair) {
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>"; //echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
$pubkey = $sigPair->getPubKey(); $pubkey = $sigPair->getPubKey();
$signature = $sigPair->getEd25519(); $signature = $sigPair->getEd25519();
if(!$createRight) { if(!$createRight) {
while($createTrys < 500) { while($createTrys < 500) {
if(\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) { if(\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
$createRight = true; $createRight = true;
break; break;
} else { } else {
$createTrys++; $createTrys++;
$created->setSeconds($created->getSeconds() - 1); $created->setSeconds($created->getSeconds() - 1);
//$body->setCreated($created); //$body->setCreated($created);
$bodyBytes = $body->serializeToString(); $bodyBytes = $body->serializeToString();
} }
} }
} }
if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) { if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
return ['state' => 'error', 'msg' => 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ']; return ['state' => 'error', 'msg' => 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid '];
} }
} }
$protoTransaction->setBodyBytes($bodyBytes); $protoTransaction->setBodyBytes($bodyBytes);
return $protoTransaction; return $protoTransaction;
} }
} }

View File

@ -1,122 +1,122 @@
<?php <?php
namespace Model\Transactions; namespace Model\Transactions;
use Cake\ORM\TableRegistry; use Cake\ORM\TableRegistry;
class TransactionBase { class TransactionBase {
private $errors = []; private $errors = [];
static $tables = []; static $tables = [];
public function getErrors() { public function getErrors() {
return $this->errors; return $this->errors;
} }
public function addError($functionName, $errorName) { public function addError($functionName, $errorName) {
array_push($this->errors, [$functionName => $errorName]); array_push($this->errors, [$functionName => $errorName]);
} }
public function addErrors($errors) { public function addErrors($errors) {
$this->errors = array_merge($this->errors, $errors); $this->errors = array_merge($this->errors, $errors);
} }
public function hasErrors() { public function hasErrors() {
return count($this->errors) > 0; return count($this->errors) > 0;
} }
public static function getTable($tableName) { public static function getTable($tableName) {
if(!isset(self::$tables[$tableName])) { if(!isset(self::$tables[$tableName])) {
self::$tables[$tableName] = TableRegistry::getTableLocator()->get($tableName); self::$tables[$tableName] = TableRegistry::getTableLocator()->get($tableName);
} }
return self::$tables[$tableName]; return self::$tables[$tableName];
} }
protected function getStateUserId($publicKey) { protected function getStateUserId($publicKey) {
$stateUsersTable = self::getTable('state_users'); $stateUsersTable = self::getTable('state_users');
$stateUser = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $publicKey])->first(); $stateUser = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $publicKey])->first();
if($stateUser) { if($stateUser) {
return $stateUser->id; return $stateUser->id;
} }
// create new entry // create new entry
$stateUserEntity = $stateUsersTable->newEntity(); $stateUserEntity = $stateUsersTable->newEntity();
$stateUserEntity->public_key = $publicKey; $stateUserEntity->public_key = $publicKey;
if($stateUsersTable->save($stateUserEntity)) { if($stateUsersTable->save($stateUserEntity)) {
return $stateUserEntity->id; return $stateUserEntity->id;
} else { } else {
$this->addError('TransactionBase::getStateUserId', 'error saving new state user with error: ' . json_encode($stateUserEntity->getErrors())); $this->addError('TransactionBase::getStateUserId', 'error saving new state user with error: ' . json_encode($stateUserEntity->getErrors()));
} }
return NULL; return NULL;
} }
protected function getStateUser($id) { protected function getStateUser($id) {
$stateUsersTable = self::getTable('state_users'); $stateUsersTable = self::getTable('state_users');
$stateUser = $stateUsersTable->get($id); $stateUser = $stateUsersTable->get($id);
if($stateUser) { if($stateUser) {
return $stateUser; return $stateUser;
} }
return NULL; return NULL;
} }
protected function updateStateBalance($stateUserId, $addAmountCent, $recordDate) { protected function updateStateBalance($stateUserId, $addAmountCent, $recordDate) {
$finalBalance = 0; $finalBalance = 0;
$stateBalancesTable = self::getTable('stateBalances'); $stateBalancesTable = self::getTable('stateBalances');
$stateBalanceQuery = $stateBalancesTable $stateBalanceQuery = $stateBalancesTable
->find('all') ->find('all')
->select(['amount', 'id']) ->select(['amount', 'id'])
->contain(false) ->contain(false)
->where(['state_user_id' => $stateUserId]);//->first(); ->where(['state_user_id' => $stateUserId]);//->first();
//debug($stateBalanceQuery); //debug($stateBalanceQuery);
if($stateBalanceQuery->count() > 0) { if($stateBalanceQuery->count() > 0) {
$stateBalanceEntry = $stateBalanceQuery->first(); $stateBalanceEntry = $stateBalanceQuery->first();
$stateBalanceEntry->amount = $stateBalanceEntry->partDecay($recordDate) + $addAmountCent; $stateBalanceEntry->amount = $stateBalanceEntry->partDecay($recordDate) + $addAmountCent;
$stateBalanceEntry->amount += $addAmountCent; $stateBalanceEntry->amount += $addAmountCent;
} else { } else {
$stateBalanceEntry = $stateBalancesTable->newEntity(); $stateBalanceEntry = $stateBalancesTable->newEntity();
$stateBalanceEntry->state_user_id = $stateUserId; $stateBalanceEntry->state_user_id = $stateUserId;
$stateBalanceEntry->amount = $addAmountCent; $stateBalanceEntry->amount = $addAmountCent;
} }
$stateBalanceEntry->record_date = $recordDate; $stateBalanceEntry->record_date = $recordDate;
$finalBalance = $stateBalanceEntry->amount; $finalBalance = $stateBalanceEntry->amount;
//echo "\ntry to save: "; var_dump($stateBalanceEntry); echo "\n"; //echo "\ntry to save: "; var_dump($stateBalanceEntry); echo "\n";
if(!$stateBalancesTable->save($stateBalanceEntry)) { if(!$stateBalancesTable->save($stateBalanceEntry)) {
$errors = $stateBalanceEntry->getErrors(); $errors = $stateBalanceEntry->getErrors();
$this->addError('TransactionBase::updateStateBalance', 'error saving state balance with: ' . json_encode($errors)); $this->addError('TransactionBase::updateStateBalance', 'error saving state balance with: ' . json_encode($errors));
return false; return false;
} }
return $finalBalance; return $finalBalance;
} }
protected function addStateUserTransaction($stateUserId, $transactionId, $transactionTypeId, $balance) { protected function addStateUserTransaction($stateUserId, $transactionId, $transactionTypeId, $balance) {
$stateUserTransactionTable = self::getTable('state_user_transactions'); $stateUserTransactionTable = self::getTable('state_user_transactions');
$stateUserTransactions = $stateUserTransactionTable $stateUserTransactions = $stateUserTransactionTable
->find('all') ->find('all')
->where(['state_user_id' => $stateUserId]) ->where(['state_user_id' => $stateUserId])
->order(['transaction_id DESC']); ->order(['transaction_id DESC']);
if($stateUserTransactions->count() > 0) { if($stateUserTransactions->count() > 0) {
$stateBalanceTable = self::getTable('state_balances'); $stateBalanceTable = self::getTable('state_balances');
$balance_entity = $stateBalanceTable->newEntity(); $balance_entity = $stateBalanceTable->newEntity();
$balance_entity->amount = $stateUserTransactions->first()->balance; $balance_entity->amount = $stateUserTransactions->first()->balance;
$balance_entity->record_date = $stateUserTransactions->first()->balance_date; $balance_entity->record_date = $stateUserTransactions->first()->balance_date;
$balance = $balance_entity->decay + $balance; $balance = $balance_entity->decay + $balance;
} }
$entity = $stateUserTransactionTable->newEntity(); $entity = $stateUserTransactionTable->newEntity();
$entity->state_user_id = $stateUserId; $entity->state_user_id = $stateUserId;
$entity->transaction_id = $transactionId; $entity->transaction_id = $transactionId;
$entity->transaction_type_id = $transactionTypeId; $entity->transaction_type_id = $transactionTypeId;
$entity->balance = $balance; $entity->balance = $balance;
if(!$stateUserTransactionTable->save($entity)) { if(!$stateUserTransactionTable->save($entity)) {
$errors = $entity->getErrors(); $errors = $entity->getErrors();
$this->addError('TransactionBase::addStateUserTransaction', 'error saving state user balance with: ' . json_encode($errors)); $this->addError('TransactionBase::addStateUserTransaction', 'error saving state user balance with: ' . json_encode($errors));
return false; return false;
} }
return true; return true;
} }
} }

View File

@ -1,46 +1,46 @@
<?php <?php
namespace App\Test\TestCase\Controller; namespace App\Test\TestCase\Controller;
use App\Controller\AppController; use App\Controller\AppController;
use Cake\TestSuite\IntegrationTestTrait; use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase; use Cake\TestSuite\TestCase;
/** /**
* App\Controller\DashboardController Test Case * App\Controller\DashboardController Test Case
* *
* @uses \App\Controller\DashboardController * @uses \App\Controller\DashboardController
*/ */
class AppControllerTest extends TestCase class AppControllerTest extends TestCase
{ {
use IntegrationTestTrait; use IntegrationTestTrait;
/** /**
* Fixtures * Fixtures
* *
* @var array * @var array
*/ */
public $fixtures = [ public $fixtures = [
'app.StateBalances' 'app.StateBalances'
]; ];
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
} }
/** /**
* Test initialize method * Test initialize method
* *
* @return void * @return void
*/ */
public function testInitialize() public function testInitialize()
{ {
$this->session(['StateUser.id' => 1]); $this->session(['StateUser.id' => 1]);
$this->get('/'); $this->get('/');
$this->assertSession(1200, 'StateUser.balance'); $this->assertSession(1200, 'StateUser.balance');
//$this->markTestIncomplete('Not implemented yet.'); //$this->markTestIncomplete('Not implemented yet.');
} }
} }

2
gn

@ -1 +1 @@
Subproject commit a61871987261614102b11ed58791081be1954d3c Subproject commit 5437e2f882c54efe4f501f7cd0d97f53806d0b74

View File

@ -1,42 +1,42 @@
#ifndef Gradido_LoginServer_INCLUDED #ifndef Gradido_LoginServer_INCLUDED
#define Gradido_LoginServer_INCLUDED #define Gradido_LoginServer_INCLUDED
#include "Poco/Util/ServerApplication.h" #include "Poco/Util/ServerApplication.h"
class Gradido_LoginServer : public Poco::Util::ServerApplication class Gradido_LoginServer : public Poco::Util::ServerApplication
{ {
/// The main application class. /// The main application class.
/// ///
/// This class handles command-line arguments and /// This class handles command-line arguments and
/// configuration files. /// configuration files.
/// Start the Gradido_LoginServer executable with the help /// Start the Gradido_LoginServer executable with the help
/// option (/help on Windows, --help on Unix) for /// option (/help on Windows, --help on Unix) for
/// the available command line options. /// the available command line options.
/// ///
public: public:
Gradido_LoginServer(); Gradido_LoginServer();
~Gradido_LoginServer(); ~Gradido_LoginServer();
protected: protected:
void initialize(Application& self); void initialize(Application& self);
void uninitialize(); void uninitialize();
void defineOptions(Poco::Util::OptionSet& options); void defineOptions(Poco::Util::OptionSet& options);
void handleOption(const std::string& name, const std::string& value); void handleOption(const std::string& name, const std::string& value);
void displayHelp(); void displayHelp();
int main(const std::vector<std::string>& args); int main(const std::vector<std::string>& args);
void createConsoleFileAsyncLogger(std::string name, std::string filePath); void createConsoleFileAsyncLogger(std::string name, std::string filePath);
private: private:
bool _helpRequested; bool _helpRequested;
std::string mConfigPath; std::string mConfigPath;
}; };
#endif //Gradido_LoginServer_INCLUDED #endif //Gradido_LoginServer_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
#ifndef AdminNodeServerTestPage_INCLUDED #ifndef AdminNodeServerTestPage_INCLUDED
#define AdminNodeServerTestPage_INCLUDED #define AdminNodeServerTestPage_INCLUDED
#include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPRequestHandler.h"
#include "PageRequestMessagedHandler.h" #include "PageRequestMessagedHandler.h"
class AdminNodeServerTestPage: public PageRequestMessagedHandler class AdminNodeServerTestPage: public PageRequestMessagedHandler
{ {
public: public:
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
}; };
#endif // AdminNodeServerTestPage_INCLUDED #endif // AdminNodeServerTestPage_INCLUDED

View File

@ -1,20 +1,20 @@
#ifndef LoginPage_INCLUDED #ifndef LoginPage_INCLUDED
#define LoginPage_INCLUDED #define LoginPage_INCLUDED
#include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPRequestHandler.h"
#include "SessionHTTPRequestHandler.h" #include "SessionHTTPRequestHandler.h"
class LoginPage: public SessionHTTPRequestHandler class LoginPage: public SessionHTTPRequestHandler
{ {
public: public:
LoginPage(Session*); LoginPage(Session*);
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
}; };
#endif // LoginPage_INCLUDED #endif // LoginPage_INCLUDED

View File

@ -1,123 +1,123 @@
#include "JsonGetUserInfos.h" #include "JsonGetUserInfos.h"
#include "../lib/DataTypeConverter.h" #include "../lib/DataTypeConverter.h"
#include "../SingletonManager/SessionManager.h" #include "../SingletonManager/SessionManager.h"
#include "../controller/User.h" #include "../controller/User.h"
#include "../controller/EmailVerificationCode.h" #include "../controller/EmailVerificationCode.h"
#include "../ServerConfig.h" #include "../ServerConfig.h"
Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params) Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
{ {
/* /*
'session_id' => $session_id, 'session_id' => $session_id,
'email' => $email, 'email' => $email,
'ask' => ['EmailOptIn.Register'] 'ask' => ['EmailOptIn.Register']
*/ */
// incoming // incoming
int session_id = 0; int session_id = 0;
std::string email; std::string email;
Poco::JSON::Array::Ptr askArray; Poco::JSON::Array::Ptr askArray;
auto sm = SessionManager::getInstance(); auto sm = SessionManager::getInstance();
// if is json object // if is json object
if (params.type() == typeid(Poco::JSON::Object::Ptr)) { if (params.type() == typeid(Poco::JSON::Object::Ptr)) {
Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>(); Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>();
/// Throws a RangeException if the value does not fit /// Throws a RangeException if the value does not fit
/// into the result variable. /// into the result variable.
/// Throws a NotImplementedException if conversion is /// Throws a NotImplementedException if conversion is
/// not available for the given type. /// not available for the given type.
/// Throws InvalidAccessException if Var is empty. /// Throws InvalidAccessException if Var is empty.
try { try {
paramJsonObject->get("email").convert(email); paramJsonObject->get("email").convert(email);
paramJsonObject->get("session_id").convert(session_id); paramJsonObject->get("session_id").convert(session_id);
askArray = paramJsonObject->getArray("ask"); askArray = paramJsonObject->getArray("ask");
} }
catch (Poco::Exception& ex) { catch (Poco::Exception& ex) {
return stateError("json exception", ex.displayText()); return stateError("json exception", ex.displayText());
} }
} }
else { else {
return stateError("parameter format unknown"); return stateError("parameter format unknown");
} }
if (!session_id) { if (!session_id) {
return stateError("session_id invalid"); return stateError("session_id invalid");
} }
if (askArray.isNull()) { if (askArray.isNull()) {
return stateError("ask is zero or not an array"); return stateError("ask is zero or not an array");
} }
auto session = sm->getSession(session_id); auto session = sm->getSession(session_id);
if (!session) { if (!session) {
return customStateError("not found", "session not found"); return customStateError("not found", "session not found");
} }
auto user = controller::User::create(); auto user = controller::User::create();
if (1 != user->load(email)) { if (1 != user->load(email)) {
return customStateError("not found", "user not found"); return customStateError("not found", "user not found");
} }
auto userModel = user->getModel(); auto userModel = user->getModel();
Poco::JSON::Object* result = new Poco::JSON::Object; Poco::JSON::Object* result = new Poco::JSON::Object;
result->set("state", "success"); result->set("state", "success");
Poco::JSON::Array jsonErrorsArray; Poco::JSON::Array jsonErrorsArray;
Poco::JSON::Object jsonUser; Poco::JSON::Object jsonUser;
Poco::JSON::Object jsonServer; Poco::JSON::Object jsonServer;
for (auto it = askArray->begin(); it != askArray->end(); it++) { for (auto it = askArray->begin(); it != askArray->end(); it++) {
auto parameter = *it; auto parameter = *it;
std::string parameterString; std::string parameterString;
try { try {
parameter.convert(parameterString); parameter.convert(parameterString);
if (parameterString == "EmailVerificationCode.Register") { if (parameterString == "EmailVerificationCode.Register") {
try { try {
auto emailVerificationCode = controller::EmailVerificationCode::load( auto emailVerificationCode = controller::EmailVerificationCode::load(
userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER
); );
if (!emailVerificationCode) { if (!emailVerificationCode) {
emailVerificationCode = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); emailVerificationCode = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER);
UniLib::controller::TaskPtr insert = new model::table::ModelInsertTask(emailVerificationCode->getModel(), false); UniLib::controller::TaskPtr insert = new model::table::ModelInsertTask(emailVerificationCode->getModel(), false);
insert->scheduleTask(insert); insert->scheduleTask(insert);
} }
jsonUser.set("EmailVerificationCode.Register", std::to_string(emailVerificationCode->getModel()->getCode())); jsonUser.set("EmailVerificationCode.Register", std::to_string(emailVerificationCode->getModel()->getCode()));
} }
catch (Poco::Exception& ex) { catch (Poco::Exception& ex) {
printf("exception: %s\n", ex.displayText().data()); printf("exception: %s\n", ex.displayText().data());
} }
} }
else if (parameterString == "loginServer.path") { else if (parameterString == "loginServer.path") {
jsonServer.set("loginServer.path", ServerConfig::g_serverPath); jsonServer.set("loginServer.path", ServerConfig::g_serverPath);
} }
else if (parameterString == "user.pubkeyhex") { else if (parameterString == "user.pubkeyhex") {
jsonUser.set("pubkeyhex", userModel->getPublicKeyHex()); jsonUser.set("pubkeyhex", userModel->getPublicKeyHex());
} }
else if (parameterString == "user.first_name") { else if (parameterString == "user.first_name") {
jsonUser.set("first_name", userModel->getFirstName()); jsonUser.set("first_name", userModel->getFirstName());
} }
else if (parameterString == "user.last_name") { else if (parameterString == "user.last_name") {
jsonUser.set("last_name", userModel->getLastName()); jsonUser.set("last_name", userModel->getLastName());
} }
else if (parameterString == "user.disabled") { else if (parameterString == "user.disabled") {
jsonUser.set("disabled", userModel->isDisabled()); jsonUser.set("disabled", userModel->isDisabled());
} }
else if (parameterString == "user.email_checked") { else if (parameterString == "user.email_checked") {
jsonUser.set("email_checked", userModel->isEmailChecked()); jsonUser.set("email_checked", userModel->isEmailChecked());
} }
else if (parameterString == "user.identHash") { else if (parameterString == "user.identHash") {
auto email = userModel->getEmail(); auto email = userModel->getEmail();
jsonUser.set("identHash", DRMakeStringHash(email.data(), email.size())); jsonUser.set("identHash", DRMakeStringHash(email.data(), email.size()));
} }
} }
catch (Poco::Exception& ex) { catch (Poco::Exception& ex) {
jsonErrorsArray.add("ask parameter invalid"); jsonErrorsArray.add("ask parameter invalid");
} }
} }
result->set("errors", jsonErrorsArray); result->set("errors", jsonErrorsArray);
result->set("userData", jsonUser); result->set("userData", jsonUser);
result->set("server", jsonServer); result->set("server", jsonServer);
return result; return result;
} }

View File

@ -1,44 +1,44 @@
#include "JsonLogout.h" #include "JsonLogout.h"
#include "../SingletonManager/SessionManager.h" #include "../SingletonManager/SessionManager.h"
Poco::JSON::Object* JsonLogout::handle(Poco::Dynamic::Var params) Poco::JSON::Object* JsonLogout::handle(Poco::Dynamic::Var params)
{ {
auto sm = SessionManager::getInstance(); auto sm = SessionManager::getInstance();
int session_id = 0; int session_id = 0;
// if is json object // if is json object
if (params.type() == typeid(Poco::JSON::Object::Ptr)) { if (params.type() == typeid(Poco::JSON::Object::Ptr)) {
Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>(); Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>();
/// Throws a RangeException if the value does not fit /// Throws a RangeException if the value does not fit
/// into the result variable. /// into the result variable.
/// Throws a NotImplementedException if conversion is /// Throws a NotImplementedException if conversion is
/// not available for the given type. /// not available for the given type.
/// Throws InvalidAccessException if Var is empty. /// Throws InvalidAccessException if Var is empty.
try { try {
paramJsonObject->get("session_id").convert(session_id); paramJsonObject->get("session_id").convert(session_id);
} }
catch (Poco::Exception& ex) { catch (Poco::Exception& ex) {
return stateError("json exception", ex.displayText()); return stateError("json exception", ex.displayText());
} }
} }
else { else {
return stateError("parameter format unknown"); return stateError("parameter format unknown");
} }
auto session = sm->getSession(session_id); auto session = sm->getSession(session_id);
if (!session) { if (!session) {
return stateError("session not found", std::to_string(session_id)); return stateError("session not found", std::to_string(session_id));
} }
if (sm->releaseSession(session_id)) { if (sm->releaseSession(session_id)) {
return stateSuccess(); return stateSuccess();
} }
return stateError("error by releasing session"); return stateError("error by releasing session");
} }

View File

@ -1,18 +1,18 @@
#ifndef __JSON_INTERFACE_JSON_LOGOUT_ #ifndef __JSON_INTERFACE_JSON_LOGOUT_
#define __JSON_INTERFACE_JSON_LOGOUT_ #define __JSON_INTERFACE_JSON_LOGOUT_
#include "JsonRequestHandler.h" #include "JsonRequestHandler.h"
class JsonLogout : public JsonRequestHandler class JsonLogout : public JsonRequestHandler
{ {
public: public:
JsonLogout(Poco::Net::IPAddress ip) : mClientIP(ip) {} JsonLogout(Poco::Net::IPAddress ip) : mClientIP(ip) {}
Poco::JSON::Object* handle(Poco::Dynamic::Var params); Poco::JSON::Object* handle(Poco::Dynamic::Var params);
protected: protected:
Poco::Net::IPAddress mClientIP; Poco::Net::IPAddress mClientIP;
}; };
#endif // __JSON_INTERFACE_JSON_LOGOUT_ #endif // __JSON_INTERFACE_JSON_LOGOUT_

View File

@ -1,19 +1,19 @@
#ifndef __JSON_INTERFACE_JSON_TRANSACTION_ #ifndef __JSON_INTERFACE_JSON_TRANSACTION_
#define __JSON_INTERFACE_JSON_TRANSACTION_ #define __JSON_INTERFACE_JSON_TRANSACTION_
#include "JsonRequestHandler.h" #include "JsonRequestHandler.h"
class Session; class Session;
class JsonTransaction : public JsonRequestHandler class JsonTransaction : public JsonRequestHandler
{ {
public: public:
Poco::JSON::Object* handle(Poco::Dynamic::Var params); Poco::JSON::Object* handle(Poco::Dynamic::Var params);
protected: protected:
bool startProcessingTransaction(Session* session, const std::string& transactionBase64); bool startProcessingTransaction(Session* session, const std::string& transactionBase64);
}; };
#endif // __JSON_INTERFACE_JSON_TRANSACTION_ #endif // __JSON_INTERFACE_JSON_TRANSACTION_

View File

@ -1,173 +1,173 @@
#include "EmailManager.h" #include "EmailManager.h"
#include "../ServerConfig.h" #include "../ServerConfig.h"
#include "../Crypto/Obfus_array.h" #include "../Crypto/Obfus_array.h"
#include "../Crypto/DRRandom.h" #include "../Crypto/DRRandom.h"
#include "../SingletonManager/LanguageManager.h" #include "../SingletonManager/LanguageManager.h"
#include "Poco/Net/SecureSMTPClientSession.h" #include "Poco/Net/SecureSMTPClientSession.h"
#include "Poco/Net/SSLException.h" #include "Poco/Net/SSLException.h"
EmailManager::EmailManager() EmailManager::EmailManager()
: Thread("emails", false), mEmailLog(Poco::Logger::get("emailLog")), mInitalized(false), mDisableEmail(false) : Thread("emails", false), mEmailLog(Poco::Logger::get("emailLog")), mInitalized(false), mDisableEmail(false)
{ {
} }
EmailManager::~EmailManager() EmailManager::~EmailManager()
{ {
exit(); exit();
} }
EmailManager* EmailManager::getInstance() EmailManager* EmailManager::getInstance()
{ {
static EmailManager theOne; static EmailManager theOne;
return &theOne; return &theOne;
} }
bool EmailManager::init(const Poco::Util::LayeredConfiguration& cfg) bool EmailManager::init(const Poco::Util::LayeredConfiguration& cfg)
{ {
try { try {
mDisableEmail = cfg.getBool("email.disable", false); mDisableEmail = cfg.getBool("email.disable", false);
if (!mDisableEmail) { if (!mDisableEmail) {
mEmailAccount.sender = cfg.getString("email.sender"); mEmailAccount.sender = cfg.getString("email.sender");
mEmailAccount.admin_receiver = cfg.getString("email.admin_receiver"); mEmailAccount.admin_receiver = cfg.getString("email.admin_receiver");
mEmailAccount.username = cfg.getString("email.username"); mEmailAccount.username = cfg.getString("email.username");
mEmailAccount.password = cfg.getString("email.password"); mEmailAccount.password = cfg.getString("email.password");
mEmailAccount.url = cfg.getString("email.smtp.url"); mEmailAccount.url = cfg.getString("email.smtp.url");
mEmailAccount.port = cfg.getInt("email.smtp.port"); mEmailAccount.port = cfg.getInt("email.smtp.port");
} }
} }
catch (Poco::Exception& ex) { catch (Poco::Exception& ex) {
printf("email account not set in config: %s\n", ex.displayText().data()); printf("email account not set in config: %s\n", ex.displayText().data());
return false; return false;
} }
Thread::init("emails"); Thread::init("emails");
mInitalized = true; mInitalized = true;
DISASM_FALSERET; DISASM_FALSERET;
ServerConfig::g_ServerKeySeed->put(3, DRRandom::r64()); ServerConfig::g_ServerKeySeed->put(3, DRRandom::r64());
return true; return true;
} }
void EmailManager::addEmail(model::Email* email) { void EmailManager::addEmail(model::Email* email) {
if (mDisableEmail) { if (mDisableEmail) {
std::string log_message = "Email should be sended to: "; std::string log_message = "Email should be sended to: ";
auto email_user = email->getUser(); auto email_user = email->getUser();
Poco::AutoPtr<model::table::User> email_model; Poco::AutoPtr<model::table::User> email_model;
if (email_user) { if (email_user) {
email_model = email_user->getModel(); email_model = email_user->getModel();
log_message += email_model->getNameWithEmailHtml(); log_message += email_model->getNameWithEmailHtml();
} }
if (email_model.isNull()) { if (email_model.isNull()) {
log_message += "<missing>"; log_message += "<missing>";
} }
log_message += ", type: "; log_message += ", type: ";
log_message += model::Email::emailTypeString(email->getType()); log_message += model::Email::emailTypeString(email->getType());
mEmailLog.log(log_message); mEmailLog.log(log_message);
delete email; delete email;
return; return;
} }
mPendingEmails.push(email); mPendingEmails.push(email);
condSignal(); condSignal();
} }
void EmailManager::exit() void EmailManager::exit()
{ {
model::Email* email = nullptr; model::Email* email = nullptr;
while (mPendingEmails.pop(email)) { while (mPendingEmails.pop(email)) {
delete email; delete email;
} }
mInitalized = false; mInitalized = false;
} }
int EmailManager::ThreadFunction() int EmailManager::ThreadFunction()
{ {
// prepare connection to email server // prepare connection to email server
if (ServerConfig::g_disableEmail) return 0; if (ServerConfig::g_disableEmail) return 0;
if (mPendingEmails.empty()) return 0; if (mPendingEmails.empty()) return 0;
auto lm = LanguageManager::getInstance(); auto lm = LanguageManager::getInstance();
Poco::Net::SecureSMTPClientSession mailClientSession(mEmailAccount.url, mEmailAccount.port); Poco::Net::SecureSMTPClientSession mailClientSession(mEmailAccount.url, mEmailAccount.port);
mailClientSession.login(); mailClientSession.login();
try { try {
mailClientSession.startTLS(ServerConfig::g_SSL_CLient_Context); mailClientSession.startTLS(ServerConfig::g_SSL_CLient_Context);
mailClientSession.login(Poco::Net::SMTPClientSession::AUTH_LOGIN, mEmailAccount.username, mEmailAccount.password); mailClientSession.login(Poco::Net::SMTPClientSession::AUTH_LOGIN, mEmailAccount.username, mEmailAccount.password);
} }
catch (Poco::Net::SSLException& ex) { catch (Poco::Net::SSLException& ex) {
printf("[PrepareEmailTask] ssl certificate error: %s\nPlease make sure you have cacert.pem (CA/root certificates) next to binary from https://curl.haxx.se/docs/caextract.html\n", ex.displayText().data()); printf("[PrepareEmailTask] ssl certificate error: %s\nPlease make sure you have cacert.pem (CA/root certificates) next to binary from https://curl.haxx.se/docs/caextract.html\n", ex.displayText().data());
return -1; return -1;
} }
model::Email* email = nullptr; model::Email* email = nullptr;
Poco::AutoPtr<LanguageCatalog> catalogs[2]; Poco::AutoPtr<LanguageCatalog> catalogs[2];
// if email list empty, wait 500ms x time before exit thread and closing connection // if email list empty, wait 500ms x time before exit thread and closing connection
int timeoutWaits = 20; int timeoutWaits = 20;
while (mPendingEmails.pop(email) || timeoutWaits > 0) { while (mPendingEmails.pop(email) || timeoutWaits > 0) {
if (email) { if (email) {
Poco::Net::MailMessage mailMessage; Poco::Net::MailMessage mailMessage;
mailMessage.setSender(mEmailAccount.sender); mailMessage.setSender(mEmailAccount.sender);
Languages lang_code = ServerConfig::g_default_locale; Languages lang_code = ServerConfig::g_default_locale;
auto email_user = email->getUser(); auto email_user = email->getUser();
if (email_user) { if (email_user) {
Poco::AutoPtr<model::table::User> userModel = email_user->getModel(); Poco::AutoPtr<model::table::User> userModel = email_user->getModel();
if (!userModel.isNull()) { if (!userModel.isNull()) {
lang_code = LanguageManager::languageFromString(userModel->getLanguageKey()); lang_code = LanguageManager::languageFromString(userModel->getLanguageKey());
if (lang_code > LANG_COUNT) lang_code = ServerConfig::g_default_locale; if (lang_code > LANG_COUNT) lang_code = ServerConfig::g_default_locale;
} }
} }
if (catalogs[lang_code].isNull()) { if (catalogs[lang_code].isNull()) {
catalogs[lang_code] = lm->getFreeCatalog(lang_code); catalogs[lang_code] = lm->getFreeCatalog(lang_code);
} }
if (email->draft(&mailMessage, catalogs[lang_code])) { if (email->draft(&mailMessage, catalogs[lang_code])) {
mailClientSession.sendMessage(mailMessage); mailClientSession.sendMessage(mailMessage);
// add for debugging // add for debugging
if (email_user) { if (email_user) {
//printf("send email to %s\n", user_model->getEmail().data()); //printf("send email to %s\n", user_model->getEmail().data());
auto user_model = email_user->getModel(); auto user_model = email_user->getModel();
std::string log_message = "Email sended to: "; std::string log_message = "Email sended to: ";
if (user_model) { if (user_model) {
log_message += email_user->getModel()->getNameWithEmailHtml(); log_message += email_user->getModel()->getNameWithEmailHtml();
} }
else { else {
log_message += "<missing>"; log_message += "<missing>";
} }
log_message += ", type: "; log_message += ", type: ";
log_message += model::Email::emailTypeString(email->getType()); log_message += model::Email::emailTypeString(email->getType());
mEmailLog.log(log_message); mEmailLog.log(log_message);
} }
} }
else { else {
// error drafting email, shouldn't happend // error drafting email, shouldn't happend
printf("[EmailManager::ThreadFunction] Error drafting email\n"); printf("[EmailManager::ThreadFunction] Error drafting email\n");
} }
delete email; delete email;
email = nullptr; email = nullptr;
} }
if (mPendingEmails.empty()) { if (mPendingEmails.empty()) {
Poco::Thread::sleep(500); Poco::Thread::sleep(500);
timeoutWaits--; timeoutWaits--;
} }
} }
mailClientSession.close(); mailClientSession.close();
return 0; return 0;
} }

View File

@ -1,47 +1,47 @@
#include "TransactionId.h" #include "TransactionId.h"
#include "../../lib/DataTypeConverter.h" #include "../../lib/DataTypeConverter.h"
namespace model { namespace model {
namespace hedera { namespace hedera {
TransactionId::TransactionId() TransactionId::TransactionId()
: shard(0), realm(0), num(0) : shard(0), realm(0), num(0)
{ {
} }
TransactionId::TransactionId(const proto::TransactionID& transaction) TransactionId::TransactionId(const proto::TransactionID& transaction)
{ {
auto account_id = transaction.accountid(); auto account_id = transaction.accountid();
shard = account_id.shardnum(); shard = account_id.shardnum();
realm = account_id.realmnum(); realm = account_id.realmnum();
num = account_id.accountnum(); num = account_id.accountnum();
mTransactionValidStart = DataTypeConverter::convertFromProtoTimestamp(transaction.transactionvalidstart()); mTransactionValidStart = DataTypeConverter::convertFromProtoTimestamp(transaction.transactionvalidstart());
} }
TransactionId::TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart) TransactionId::TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart)
: shard(shard), realm(realm), num(num), mTransactionValidStart(transactionValidStart) : shard(shard), realm(realm), num(num), mTransactionValidStart(transactionValidStart)
{ {
} }
TransactionId::~TransactionId() TransactionId::~TransactionId()
{ {
} }
Poco::JSON::Object::Ptr TransactionId::convertToJSON() Poco::JSON::Object::Ptr TransactionId::convertToJSON()
{ {
Poco::JSON::Object::Ptr result = new Poco::JSON::Object; Poco::JSON::Object::Ptr result = new Poco::JSON::Object;
result->set("transactionValidStart", mTransactionValidStart); result->set("transactionValidStart", mTransactionValidStart);
Poco::JSON::Object accountId; Poco::JSON::Object accountId;
accountId.set("shard", shard); accountId.set("shard", shard);
accountId.set("realm", realm); accountId.set("realm", realm);
accountId.set("num", num); accountId.set("num", num);
result->set("accountId", accountId); result->set("accountId", accountId);
return result; return result;
} }
} }
} }

View File

@ -1,424 +1,424 @@
<%@ page class="AdminNodeServerTestPage" %> <%@ page class="AdminNodeServerTestPage" %>
<%@ page form="true" %> <%@ page form="true" %>
<%@ page compressed="true" %> <%@ page compressed="true" %>
<%@ page baseClass="PageRequestMessagedHandler" %> <%@ page baseClass="PageRequestMessagedHandler" %>
<%@ header include="PageRequestMessagedHandler.h" %> <%@ header include="PageRequestMessagedHandler.h" %>
<%! <%!
#include "../controller/NodeServer.h" #include "../controller/NodeServer.h"
#include "../controller/User.h" #include "../controller/User.h"
#include "../controller/HederaTopic.h" #include "../controller/HederaTopic.h"
#include "../lib/DataTypeConverter.h" #include "../lib/DataTypeConverter.h"
#include "../lib/Profiler.h" #include "../lib/Profiler.h"
#include "../lib/JsonRPCRequest.h" #include "../lib/JsonRPCRequest.h"
#include "../model/gradido/Transaction.h" #include "../model/gradido/Transaction.h"
#include "Poco/Thread.h" #include "Poco/Thread.h"
#include "Poco/DateTime.h" #include "Poco/DateTime.h"
#include "Poco/JSON/Stringifier.h" #include "Poco/JSON/Stringifier.h"
enum PageType enum PageType
{ {
PAGE_CHOOSE_TEST, PAGE_CHOOSE_TEST,
PAGE_RUN_4_SET_TEST, PAGE_RUN_4_SET_TEST,
PAGE_GET_TRANSACTION_RPC_CALL PAGE_GET_TRANSACTION_RPC_CALL
}; };
%> %>
<%% <%%
const char* pageName = "Node Server Test"; const char* pageName = "Node Server Test";
PageType page = PAGE_CHOOSE_TEST; PageType page = PAGE_CHOOSE_TEST;
Poco::AutoPtr<controller::NodeServer> node_server; Poco::AutoPtr<controller::NodeServer> node_server;
Poco::AutoPtr<controller::NodeServer> node_server2; Poco::AutoPtr<controller::NodeServer> node_server2;
Poco::AutoPtr<controller::User> user; Poco::AutoPtr<controller::User> user;
Poco::AutoPtr<controller::HederaTopic> hedera_topic; Poco::AutoPtr<controller::HederaTopic> hedera_topic;
Poco::AutoPtr<controller::HederaTopic> hedera_topic2; Poco::AutoPtr<controller::HederaTopic> hedera_topic2;
int hedera_timeout = 4; int hedera_timeout = 4;
int sleep_ms_between_transactions = 1000; int sleep_ms_between_transactions = 1000;
bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); bool steps[8]; memset(steps, 1, 8 * sizeof(bool));
if(!form.empty()) if(!form.empty())
{ {
auto node_server_id_string = form.get("test-node-servers", ""); auto node_server_id_string = form.get("test-node-servers", "");
if(node_server_id_string != "") { if(node_server_id_string != "") {
int node_server_id = 0; int node_server_id = 0;
if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) {
node_server = controller::NodeServer::load(node_server_id); node_server = controller::NodeServer::load(node_server_id);
} }
} }
node_server_id_string = form.get("test-node-servers2", ""); node_server_id_string = form.get("test-node-servers2", "");
if(node_server_id_string != "") { if(node_server_id_string != "") {
int node_server_id = 0; int node_server_id = 0;
if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) {
node_server2 = controller::NodeServer::load(node_server_id); node_server2 = controller::NodeServer::load(node_server_id);
} }
} }
auto topic_id_string = form.get("test-hedera-topic", ""); auto topic_id_string = form.get("test-hedera-topic", "");
if(topic_id_string != "") { if(topic_id_string != "") {
int topic_id = 0; int topic_id = 0;
if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) {
hedera_topic = controller::HederaTopic::load(topic_id); hedera_topic = controller::HederaTopic::load(topic_id);
} }
} }
topic_id_string = form.get("test-hedera-topic2", ""); topic_id_string = form.get("test-hedera-topic2", "");
if(topic_id_string != "") { if(topic_id_string != "") {
int topic_id = 0; int topic_id = 0;
if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) {
hedera_topic2 = controller::HederaTopic::load(topic_id); hedera_topic2 = controller::HederaTopic::load(topic_id);
} }
} }
auto test_timeout_string = form.get("test-timeout", ""); auto test_timeout_string = form.get("test-timeout", "");
if(test_timeout_string != "") { if(test_timeout_string != "") {
DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); DataTypeConverter::strToInt(test_timeout_string, hedera_timeout);
} }
auto test_part_timeout_string = form.get("test-part-timeout", ""); auto test_part_timeout_string = form.get("test-part-timeout", "");
if(test_part_timeout_string != "") { if(test_part_timeout_string != "") {
DataTypeConverter::strToInt(test_part_timeout_string, sleep_ms_between_transactions); DataTypeConverter::strToInt(test_part_timeout_string, sleep_ms_between_transactions);
} }
auto submit = form.get("submit", ""); auto submit = form.get("submit", "");
if(submit == "Run 6-Test") { if(submit == "Run 6-Test") {
page = PAGE_RUN_4_SET_TEST; page = PAGE_RUN_4_SET_TEST;
} else if(submit == "json-rpc getTransactions") { } else if(submit == "json-rpc getTransactions") {
page = PAGE_GET_TRANSACTION_RPC_CALL; page = PAGE_GET_TRANSACTION_RPC_CALL;
} }
std::string step_temp; std::string step_temp;
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
std::string name = "step-"; std::string name = "step-";
name += std::to_string(i+2); name += std::to_string(i+2);
step_temp = form.get(name, ""); step_temp = form.get(name, "");
if(step_temp == "1") { if(step_temp == "1") {
steps[i] = true; steps[i] = true;
} else { } else {
steps[i] = false; steps[i] = false;
} }
} }
} }
auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE); auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE);
auto hedera_topics = controller::HederaTopic::listAll(); auto hedera_topics = controller::HederaTopic::listAll();
%><%@ include file="header_large.cpsp" %> %><%@ include file="header_large.cpsp" %>
<%= getErrorsHtml() %> <%= getErrorsHtml() %>
<div class="center-form-container"> <div class="center-form-container">
<!-- Tab links --> <!-- Tab links -->
<div class="tab"> <div class="tab">
<button class="tablinks <% if(PAGE_RUN_4_SET_TEST == page) { %> active <% } %>" onclick="openTab(event, 'test-4')">Test 6-Set (3 AddMember, Creation, 2 Transfer)</button> <button class="tablinks <% if(PAGE_RUN_4_SET_TEST == page) { %> active <% } %>" onclick="openTab(event, 'test-4')">Test 6-Set (3 AddMember, Creation, 2 Transfer)</button>
<button class="tablinks <% if(PAGE_GET_TRANSACTION_RPC_CALL == page) { %> active <% } %>" onclick="openTab(event, 'gn-jsonrpc')" title="call via json-rpc to gradido node with getTransactions">getTransactions</button> <button class="tablinks <% if(PAGE_GET_TRANSACTION_RPC_CALL == page) { %> active <% } %>" onclick="openTab(event, 'gn-jsonrpc')" title="call via json-rpc to gradido node with getTransactions">getTransactions</button>
</div> </div>
<div id="test-4" class="tabcontent" <% if(PAGE_RUN_4_SET_TEST == page) { %> style="display:block" <% } %>> <div id="test-4" class="tabcontent" <% if(PAGE_RUN_4_SET_TEST == page) { %> style="display:block" <% } %>>
<div class="center-form-title"> <div class="center-form-title">
<h3>Test 6-Set (3 AddMember, Creation, 2 Transfer)</</h3> <h3>Test 6-Set (3 AddMember, Creation, 2 Transfer)</</h3>
</div> </div>
<div class="center-form-form"> <div class="center-form-form">
<form method="POST" action="<%= getBaseUrl() %>/adminNodeServerTest"> <form method="POST" action="<%= getBaseUrl() %>/adminNodeServerTest">
<p>1. Create three new accounts and show user public keys for comparisation</p> <p>1. Create three new accounts and show user public keys for comparisation</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[0]) { %> checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[0]) { %> checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[1]) { %> checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[1]) { %> checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[2]) { %> checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[2]) { %> checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[3]) { %> checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[3]) { %> checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[4]) { %> checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[4]) { %> checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[5]) { %> checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[5]) { %> checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[6]) { %> checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[6]) { %> checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions</p>
<p><input class="form-checkbox" type="checkbox" <% if(steps[7]) { %> checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result</p> <p><input class="form-checkbox" type="checkbox" <% if(steps[7]) { %> checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result</p>
<fieldset> <fieldset>
<legend>Group 1 </legend> <legend>Group 1 </legend>
<label class="form-label" for="test-node-servers">Node Server for tests</label> <label class="form-label" for="test-node-servers">Node Server for tests</label>
<% if(node_servers.size() == 0) { %> <% if(node_servers.size() == 0) { %>
<a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a> <a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a>
<% } %> <% } %>
<select name="test-node-servers" id="test-node-servers"> <select name="test-node-servers" id="test-node-servers">
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
auto model = (*it)->getModel(); auto model = (*it)->getModel();
%> %>
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server.isNull() && node_server->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option> <option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server.isNull() && node_server->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option>
<% } %> <% } %>
</select> </select>
<label class="form-label" for="test-hedera-topic">Hedera Topic for tests</label> <label class="form-label" for="test-hedera-topic">Hedera Topic for tests</label>
<% if(hedera_topics.size() == 0) { %> <% if(hedera_topics.size() == 0) { %>
<a href="<%= getBaseUrl() %>/topic"><span class="link-title">Edit Hedera-Topics</span></a> <a href="<%= getBaseUrl() %>/topic"><span class="link-title">Edit Hedera-Topics</span></a>
<% } %> <% } %>
<select name="test-hedera-topic" id="test-hedera-topic"> <select name="test-hedera-topic" id="test-hedera-topic">
<% for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) { <% for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) {
auto model = (*it)->getModel(); auto model = (*it)->getModel();
auto hedera_account = (*it)->getAutoRenewAccount(); auto hedera_account = (*it)->getAutoRenewAccount();
if(hedera_account->getModel()->getNetworkType() != ServerConfig::HEDERA_TESTNET) { if(hedera_account->getModel()->getNetworkType() != ServerConfig::HEDERA_TESTNET) {
continue; continue;
} }
%> %>
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!hedera_topic.isNull() && hedera_topic->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getName() %>, group: <%= model->getGroupId() %></option> <option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!hedera_topic.isNull() && hedera_topic->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getName() %>, group: <%= model->getGroupId() %></option>
<% } %> <% } %>
</select> </select>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>Group 2 </legend> <legend>Group 2 </legend>
<label class="form-label" for="test-node-servers2">Node Server for tests</label> <label class="form-label" for="test-node-servers2">Node Server for tests</label>
<% if(node_servers.size() == 0) { %> <% if(node_servers.size() == 0) { %>
<a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a> <a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a>
<% } %> <% } %>
<select name="test-node-servers2" id="test-node-servers2"> <select name="test-node-servers2" id="test-node-servers2">
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
auto model = (*it)->getModel(); auto model = (*it)->getModel();
%> %>
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server2.isNull() && node_server2->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option> <option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server2.isNull() && node_server2->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option>
<% } %> <% } %>
</select> </select>
<label class="form-label" for="test-hedera-topic2">Hedera Topic for tests</label> <label class="form-label" for="test-hedera-topic2">Hedera Topic for tests</label>
<% if(hedera_topics.size() == 0) { %> <% if(hedera_topics.size() == 0) { %>
<a href="<%= getBaseUrl() %>/topic"><span class="link-title">Edit Hedera-Topics</span></a> <a href="<%= getBaseUrl() %>/topic"><span class="link-title">Edit Hedera-Topics</span></a>
<% } %> <% } %>
<select name="test-hedera-topic2" id="test-hedera-topic2"> <select name="test-hedera-topic2" id="test-hedera-topic2">
<% for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) { <% for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) {
auto model = (*it)->getModel(); auto model = (*it)->getModel();
auto hedera_account = (*it)->getAutoRenewAccount(); auto hedera_account = (*it)->getAutoRenewAccount();
if(hedera_account->getModel()->getNetworkType() != ServerConfig::HEDERA_TESTNET) { if(hedera_account->getModel()->getNetworkType() != ServerConfig::HEDERA_TESTNET) {
continue; continue;
} }
%> %>
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!hedera_topic2.isNull() && hedera_topic2->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getName() %>, group: <%= model->getGroupId() %></option> <option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!hedera_topic2.isNull() && hedera_topic2->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getName() %>, group: <%= model->getGroupId() %></option>
<% } %> <% } %>
</select> </select>
</fieldset> </fieldset>
<label class="form-label" for="test-timeout">Timeout waiting for hedera in seconds</label> <label class="form-label" for="test-timeout">Timeout waiting for hedera in seconds</label>
<input name="test-timeout" id="test-timeout" type="number" value="<%= hedera_timeout %>"> seconds <input name="test-timeout" id="test-timeout" type="number" value="<%= hedera_timeout %>"> seconds
<label class="form-label" for="test-part-timeout">Timeout between transactions to prevent out-of-order</label> <label class="form-label" for="test-part-timeout">Timeout between transactions to prevent out-of-order</label>
<input name="test-part-timeout" id="test-part-timeout" type="number" value="<%= sleep_ms_between_transactions %>"> ms <input name="test-part-timeout" id="test-part-timeout" type="number" value="<%= sleep_ms_between_transactions %>"> ms
<input class="center-form-submit form-button" type="submit" name="submit" value="Run 6-Test"> <input class="center-form-submit form-button" type="submit" name="submit" value="Run 6-Test">
</form> </form>
</div> </div>
</div> </div>
<div id="gn-jsonrpc" class="tabcontent" <% if(PAGE_GET_TRANSACTION_RPC_CALL == page) { %> style="display:block" <% } %>> <div id="gn-jsonrpc" class="tabcontent" <% if(PAGE_GET_TRANSACTION_RPC_CALL == page) { %> style="display:block" <% } %>>
<div class="center-form-title"> <div class="center-form-title">
<h3>Test 4-Set (2 AddMember, Creation, Transfer)</</h3> <h3>Test 4-Set (2 AddMember, Creation, Transfer)</</h3>
</div> </div>
<div class="center-form-form"> <div class="center-form-form">
<form method="POST" action="<%= getBaseUrl() %>/adminNodeServerTest"> <form method="POST" action="<%= getBaseUrl() %>/adminNodeServerTest">
<label class="form-label" for="test-node-servers">Node Server to call</label> <label class="form-label" for="test-node-servers">Node Server to call</label>
<% if(node_servers.size() == 0) { %> <% if(node_servers.size() == 0) { %>
<a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a> <a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a>
<% } %> <% } %>
<select name="test-node-servers" id="test-node-servers"> <select name="test-node-servers" id="test-node-servers">
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
auto model = (*it)->getModel(); auto model = (*it)->getModel();
%> %>
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server.isNull() && node_server->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option> <option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server.isNull() && node_server->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option>
<% } %> <% } %>
</select> </select>
<input class="center-form-submit form-button" type="submit" name="submit" value="json-rpc getTransactions"> <input class="center-form-submit form-button" type="submit" name="submit" value="json-rpc getTransactions">
</form> </form>
</div> </div>
</div> </div>
<% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %> <% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %>
<ul> <ul>
<li> <li>
<p>1. Create three new accounts and show user public keys for comparisation: </p> <p>1. Create three new accounts and show user public keys for comparisation: </p>
<% <%
Profiler time2; Profiler time2;
auto group_id = hedera_topic->getModel()->getGroupId(); auto group_id = hedera_topic->getModel()->getGroupId();
auto group_id2 = hedera_topic2->getModel()->getGroupId(); auto group_id2 = hedera_topic2->getModel()->getGroupId();
auto user_group = controller::Group::load(group_id); auto user_group = controller::Group::load(group_id);
auto user_group2 = controller::Group::load(group_id2); auto user_group2 = controller::Group::load(group_id2);
auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER;
std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj";
auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id); auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id);
auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]);
auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1); auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1);
user_1->setGradidoKeyPair(gradido_key_pair_1); user_1->setGradidoKeyPair(gradido_key_pair_1);
user_1->login(password1); user_1->login(password1);
std::string password2 = "uweia8saiSale,dsasA"; std::string password2 = "uweia8saiSale,dsasA";
auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id); auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id);
auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]);
auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2);
user_2->setGradidoKeyPair(gradido_key_pair_2); user_2->setGradidoKeyPair(gradido_key_pair_2);
user_2->login(password2); user_2->login(password2);
std::string password3 = "jaue_skaiellasealaK"; std::string password3 = "jaue_skaiellasealaK";
auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2);
auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]);
auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3);
user_3->setGradidoKeyPair(gradido_key_pair_3); user_3->setGradidoKeyPair(gradido_key_pair_3);
user_3->login(password3); user_3->login(password3);
%> %>
<fieldset><legend><%= user_group->getModel()->getName() %></legend> <fieldset><legend><%= user_group->getModel()->getName() %></legend>
<p>User 1: <%= user_1->getPublicHex() %></p> <p>User 1: <%= user_1->getPublicHex() %></p>
<p>User 2: <%= user_2->getPublicHex() %></p> <p>User 2: <%= user_2->getPublicHex() %></p>
</fieldset> </fieldset>
<fieldset><legend><%= user_group2->getModel()->getName() %></legend> <fieldset><legend><%= user_group2->getModel()->getName() %></legend>
<p>User 3: <%= user_3->getPublicHex() %></p> <p>User 3: <%= user_3->getPublicHex() %></p>
</fieldset> </fieldset>
<p>Time: <%= time2.string() %> <p>Time: <%= time2.string() %>
</li> </li>
<li> <li>
<p>2. Send a add-member transaction to hedera topic with one signature (first user)</p> <p>2. Send a add-member transaction to hedera topic with one signature (first user)</p>
<% <%
time2.reset(); time2.reset();
if(!steps[0]) { %> if(!steps[0]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group);
transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1);
transaction1->sign(user_1); transaction1->sign(user_1);
auto transaction1_json = transaction1->getTransactionAsJson(true); auto transaction1_json = transaction1->getTransactionAsJson(true);
%> %>
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction1_json) %></p> <p><%= DataTypeConverter::replaceNewLineWithBr(transaction1_json) %></p>
<% } %> <% } %>
<p>Time: <%= time2.string() %> <p>Time: <%= time2.string() %>
</li> </li>
<li> <li>
<p>3. Send a add-member transaction to hedera topic with two signatures (first user and second user)</p> <p>3. Send a add-member transaction to hedera topic with two signatures (first user and second user)</p>
<% <%
time2.reset(); time2.reset();
if(!steps[1]) { %> if(!steps[1]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group);
transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2);
transaction2->sign(user_2); transaction2->sign(user_2);
// wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time
Poco::Thread::sleep(sleep_ms_between_transactions); Poco::Thread::sleep(sleep_ms_between_transactions);
transaction2->sign(user_1); transaction2->sign(user_1);
auto transaction2_json = transaction2->getTransactionAsJson(true); auto transaction2_json = transaction2->getTransactionAsJson(true);
%> %>
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction2_json) %></p> <p><%= DataTypeConverter::replaceNewLineWithBr(transaction2_json) %></p>
<% } %> <% } %>
<p>Time: <%= time2.string() %> <p>Time: <%= time2.string() %>
</li> </li>
<li> <li>
<p>4. Send a creation transaction to second user, signed by first user</p> <p>4. Send a creation transaction to second user, signed by first user</p>
<% <%
time2.reset(); time2.reset();
if(!steps[2]) { %> if(!steps[2]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation");
// wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time
Poco::Thread::sleep(sleep_ms_between_transactions); Poco::Thread::sleep(sleep_ms_between_transactions);
transaction3->sign(user_1); transaction3->sign(user_1);
auto transaction3_json = transaction3->getTransactionAsJson(true); auto transaction3_json = transaction3->getTransactionAsJson(true);
%> %>
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction3_json) %></p> <p><%= DataTypeConverter::replaceNewLineWithBr(transaction3_json) %></p>
<% } %> <% } %>
<p>Time: <%= time2.string() %></p> <p>Time: <%= time2.string() %></p>
</li> </li>
<li> <li>
<p>5. Send a transfer transaction from second user to first user signed by second user</p> <p>5. Send a transfer transaction from second user to first user signed by second user</p>
<% <%
time2.reset(); time2.reset();
if(!steps[3]) { %> if(!steps[3]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy();
auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer");
// wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time
Poco::Thread::sleep(sleep_ms_between_transactions); Poco::Thread::sleep(sleep_ms_between_transactions);
transaction4[0]->sign(user_2); transaction4[0]->sign(user_2);
auto transaction4_json = transaction4[0]->getTransactionAsJson(true); auto transaction4_json = transaction4[0]->getTransactionAsJson(true);
%> %>
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction4_json) %></p> <p><%= DataTypeConverter::replaceNewLineWithBr(transaction4_json) %></p>
<% } %> <% } %>
<p>Time: <%= time2.string() %></p> <p>Time: <%= time2.string() %></p>
</li> </li>
<li> <li>
<p>6. Send a add-member transaction to hedera topic 2 with one signature (third user)</p> <p>6. Send a add-member transaction to hedera topic 2 with one signature (third user)</p>
<% <%
time2.reset(); time2.reset();
if(!steps[4]) { %> if(!steps[4]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2);
transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1);
Poco::Thread::sleep(sleep_ms_between_transactions); Poco::Thread::sleep(sleep_ms_between_transactions);
transaction5->sign(user_3); transaction5->sign(user_3);
auto transaction5_json = transaction5->getTransactionAsJson(true); auto transaction5_json = transaction5->getTransactionAsJson(true);
%> %>
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %></p> <p><%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %></p>
<% } %> <% } %>
<p>Time: <%= time2.string() %></p> <p>Time: <%= time2.string() %></p>
</li> </li>
<li> <li>
<p>7. Send a cross group transfer from second user to third user signed by second user</p> <p>7. Send a cross group transfer from second user to third user signed by second user</p>
<% <%
time2.reset(); time2.reset();
if(!steps[5]) { %> if(!steps[5]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy();
auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false);
if(!transaction6.size()) { if(!transaction6.size()) {
%> %>
<div class="alert alert-error" role="alert"> <div class="alert alert-error" role="alert">
<i class="material-icons-outlined">report_problem</i> <i class="material-icons-outlined">report_problem</i>
<span>Error creating Transaction</span> <span>Error creating Transaction</span>
</div> </div>
<% <%
} else { } else {
Poco::Thread::sleep(sleep_ms_between_transactions); Poco::Thread::sleep(sleep_ms_between_transactions);
transaction6[0]->sign(user_2); transaction6[0]->sign(user_2);
auto transaction6_json = transaction6[0]->getTransactionAsJson(true); auto transaction6_json = transaction6[0]->getTransactionAsJson(true);
auto paired_transaction = transaction6[0]->getPairedTransaction(); auto paired_transaction = transaction6[0]->getPairedTransaction();
%> %>
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %></p> <p><%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %></p>
<% if(!paired_transaction.isNull()) { <% if(!paired_transaction.isNull()) {
auto transaction6_2_json = paired_transaction->getTransactionAsJson(true); auto transaction6_2_json = paired_transaction->getTransactionAsJson(true);
%><p><%= DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) %></p> %><p><%= DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) %></p>
<% } %> <% } %>
<% } %> <% } %>
<% } %> <% } %>
<p>Time: <%= time2.string() %></p> <p>Time: <%= time2.string() %></p>
</li> </li>
<li> <li>
<p>8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions</p> <p>8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions</p>
<% if(!steps[6]) { %> <% if(!steps[6]) { %>
<p>skipped</p> <p>skipped</p>
<% } else { <% } else {
Poco::Thread::sleep(hedera_timeout * 1000); Poco::Thread::sleep(hedera_timeout * 1000);
} %> } %>
</li> </li>
<li> <li>
<p>9. Ask choosen node for transaction and print result</p> <p>9. Ask choosen node for transaction and print result</p>
<% time2.reset(); <% time2.reset();
if(!steps[7] || node_server.isNull()) { if(!steps[7] || node_server.isNull()) {
%><p>skipped</p> %><p>skipped</p>
<% } else { <% } else {
auto node_server_model = node_server->getModel(); auto node_server_model = node_server->getModel();
JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort());
Poco::JSON::Object params; Poco::JSON::Object params;
params.set("groupAlias", user_group->getModel()->getAlias()); params.set("groupAlias", user_group->getModel()->getAlias());
params.set("lastKnownSequenceNumber", 0); params.set("lastKnownSequenceNumber", 0);
auto gn_answear = jsonrpc.request("getTransactions", params); auto gn_answear = jsonrpc.request("getTransactions", params);
if(!gn_answear.isNull()) { if(!gn_answear.isNull()) {
std::stringstream ss; std::stringstream ss;
Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER);
std::string answear_string = ss.str(); %> std::string answear_string = ss.str(); %>
<%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><% <%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><%
} }
} %> } %>
<p>Time: <%= time2.string() %></p> <p>Time: <%= time2.string() %></p>
</li> </li>
</ul> </ul>
<% } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { <% } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) {
Profiler time3; Profiler time3;
auto node_server_model = node_server->getModel(); auto node_server_model = node_server->getModel();
auto user_group = controller::Group::load(node_server_model->getGroupId()); auto user_group = controller::Group::load(node_server_model->getGroupId());
JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort());
Poco::JSON::Object params; Poco::JSON::Object params;
params.set("groupAlias", user_group->getModel()->getAlias()); params.set("groupAlias", user_group->getModel()->getAlias());
params.set("lastKnownSequenceNumber", 0); params.set("lastKnownSequenceNumber", 0);
auto gn_answear = jsonrpc.request("getTransactions", params); auto gn_answear = jsonrpc.request("getTransactions", params);
if(!gn_answear.isNull()) { if(!gn_answear.isNull()) {
std::stringstream ss; std::stringstream ss;
Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER);
std::string answear_string = ss.str();%> std::string answear_string = ss.str();%>
<%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><% <%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><%
} }
%> %>
<p>Time: <%= time3.string() %></p> <p>Time: <%= time3.string() %></p>
<% } %> <% } %>
</div> </div>
<script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/tabs.js"></script> <script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/tabs.js"></script>
<%@ include file="footer.cpsp" %> <%@ include file="footer.cpsp" %>