updates for hedera transactions and saving crypto keys also clear un-encrypted

This commit is contained in:
Dario 2020-09-09 19:34:00 +02:00 committed by Ulf Gebhardt
parent 73d10f7773
commit 266ef2c92a
No known key found for this signature in database
GPG Key ID: 81308EFE29ABFEBD
32 changed files with 651 additions and 105 deletions

View File

@ -1,6 +1,7 @@
CREATE TABLE `hedera_topics` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`topic_hedera_id` int unsigned NOT NULL,
`name` VARCHAR(255) NOT NULL DEFAULT '',
`auto_renew_account_hedera_id` int unsigned DEFAULT NULL,
`auto_renew_period` int unsigned NOT NULL DEFAULT '0',
`group_id` int unsigned NOT NULL,

View File

@ -10,7 +10,7 @@ KeyPairHedera::KeyPairHedera()
}
KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/)
KeyPairHedera::KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/)
: mPrivateKey(nullptr)
{
auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420");
@ -19,27 +19,28 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* p
auto mm = MemoryManager::getInstance();
if (privateKey) {
switch (privateKey->size()) {
switch (privateKeySize) {
case 48:
// key with prefix
if (0 == sodium_memcmp(*privateKey, *derPrefixPriv, derPrefixPriv->size())) {
if (0 == sodium_memcmp(privateKey, *derPrefixPriv, derPrefixPriv->size())) {
//int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed);
auto seed = mm->getFreeMemory(crypto_sign_ed25519_SEEDBYTES);
memcpy(*seed, privateKey->data(derPrefixPriv->size()), crypto_sign_ed25519_SEEDBYTES);
createKeyFromSeed(seed);
memcpy(*seed, &privateKey[derPrefixPriv->size()], crypto_sign_ed25519_SEEDBYTES);
createKeyFromSeed(seed->data(), seed->size());
mm->releaseMemory(seed);
break;
}
case 32:
createKeyFromSeed(privateKey);
createKeyFromSeed(privateKey, privateKeySize);
break;
case 64:
//mPrivateKey = privateKey;
if (!mPrivateKey || mPrivateKey->size() != privateKey->size()) {
if (!mPrivateKey || mPrivateKey->size() != privateKeySize) {
if (mPrivateKey) {
mm->releaseMemory(mPrivateKey);
}
mPrivateKey = mm->getFreeMemory(privateKey->size());
memcpy(*mPrivateKey, *privateKey, privateKey->size());
mPrivateKey = mm->getFreeMemory(privateKeySize);
memcpy(*mPrivateKey, privateKey, privateKeySize);
}
break;
default:
@ -75,11 +76,17 @@ KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const unsigned char* p
mm->releaseMemory(derPrefixPub);
}
KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/)
: KeyPairHedera(privateKey, publicKey->data(), publicKey->size())
: KeyPairHedera(privateKey->data(), privateKey->size(), publicKey->data(), publicKey->size())
{
}
KeyPairHedera::KeyPairHedera(const std::vector<unsigned char>& privateKey, const unsigned char* publicKey/* = nullptr*/, size_t publicKeySize/* = 0*/)
: KeyPairHedera(privateKey.data(), privateKey.size(), publicKey, publicKeySize)
{
}
KeyPairHedera::~KeyPairHedera()
{
auto mm = MemoryManager::getInstance();
@ -90,13 +97,13 @@ KeyPairHedera::~KeyPairHedera()
}
void KeyPairHedera::createKeyFromSeed(const MemoryBin* seed)
void KeyPairHedera::createKeyFromSeed(const unsigned char* seed, size_t seedSize)
{
assert(seed && seed->size() == crypto_sign_ed25519_SEEDBYTES);
assert(seed && seedSize == crypto_sign_ed25519_SEEDBYTES);
auto mm = MemoryManager::getInstance();
auto secret_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES);
crypto_sign_seed_keypair(mPublicKey, *secret_key, *seed);
crypto_sign_seed_keypair(mPublicKey, *secret_key, seed);
if (mPrivateKey) {
mm->releaseMemory(mPrivateKey);
@ -177,6 +184,15 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr<SecretKeyCryptog
}
MemoryBin* KeyPairHedera::getPrivateKeyCopy() const
{
if (!mPrivateKey) return nullptr;
auto mm = MemoryManager::getInstance();
MemoryBin* private_key_copy = mm->getFreeMemory(mPrivateKey->size());
memcpy(*private_key_copy, *mPrivateKey, mPrivateKey->size());
return private_key_copy;
}
MemoryBin* KeyPairHedera::getPublicKeyCopy() const
{
auto mm = MemoryManager::getInstance();

View File

@ -22,8 +22,9 @@ public:
//! \param privateKey: copy
//! \param publicKey: copy
//!
KeyPairHedera(const MemoryBin* privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0);
KeyPairHedera(const unsigned char* privateKey, size_t privateKeySize, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0);
KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr);
KeyPairHedera(const std::vector<unsigned char>& privateKey, const unsigned char* publicKey = nullptr, size_t publicKeySize = 0);
~KeyPairHedera();
@ -64,13 +65,14 @@ public:
inline bool hasPrivateKey() const { return mPrivateKey != nullptr; }
//! \brief only way to get a private key.. encrypted
//! \brief
MemoryBin* getCryptedPrivKey(const Poco::AutoPtr<SecretKeyCryptography> password) const;
MemoryBin* getPrivateKeyCopy() const;
protected:
KeyPairHedera();
void createKeyFromSeed(const MemoryBin* seed);
void createKeyFromSeed(const unsigned char* seed, size_t seedSize);
private:

View File

@ -70,7 +70,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
addError(new Error("Action Update Balance", "hedera id not found"));
} else {
hedera_time.reset();
hedera_account[0]->updateBalanceFromHedera(user, this);
hedera_account[0]->hederaAccountGetBalance(user, this);
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
}
}
@ -318,7 +318,8 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
responseStream << ( gettext("Add Account") );
responseStream << "\">\n";
responseStream << "\t</form>\n";
responseStream << "\t\t</form>\n";
responseStream << "\t</div>\n";
responseStream << "</div>\n";
// begin include footer.cpsp
responseStream << " <div class=\"center-bottom\">\n";

View File

@ -7,8 +7,10 @@
#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#include "../controller/HederaAccount.h"
#include "../controller/Group.h"
#include "../ServerConfig.h"
#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
#include "../ServerConfig.h"
@ -27,20 +29,34 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
if (_compressResponse) response.set("Content-Encoding", "gzip");
Poco::Net::HTMLForm form(request, request.stream());
#line 10 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 12 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
const char* pageName = "Topic";
auto user = mSession->getNewUser();
int auto_renew_period = 604800; // 7 Tage
int auto_renew_account = 0;
int group_id = 0;
auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID());
auto groups = controller::Group::listAll();
std::map<int, int> group_indices;
int count = 0;
for(auto it = groups.begin(); it != groups.end(); it++) {
group_indices.insert(std::pair<int, int>((*it)->getModel()->getID(), count));
count++;
}
#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#line 3 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
bool withMaterialIcons = false;
std::ostream& _responseStream = response.send();
Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1);
std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;
responseStream << "\n";
// begin include header_large.cpsp
// begin include header.cpsp
responseStream << "\n";
responseStream << "<!DOCTYPE html>\n";
responseStream << "<html>\n";
@ -48,57 +64,132 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "<meta charset=\"UTF-8\">\n";
responseStream << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n";
responseStream << "<title>Gradido Login Server: ";
#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#line 11 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( pageName );
responseStream << "</title>\n";
responseStream << "<link rel=\"stylesheet\" type=\"text/css\" href=\"";
#line 12 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#line 12 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "css/main.css\">\n";
#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#line 13 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
if(withMaterialIcons) { responseStream << "\n";
responseStream << "<link rel=\"stylesheet\" type=\"text/css\" href=\"";
#line 14 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#line 14 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "css/materialdesignicons.min.css\">\n";
#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
#line 15 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
} responseStream << "\n";
responseStream << "</head>\n";
responseStream << "<body>\n";
responseStream << " <div class=\"layout\">\n";
responseStream << "\t\t<div class=\"sidebar1 nav-menu initial\">\n";
responseStream << "\t\t\t<div class=\"nav-vertical\">\n";
responseStream << "\t\t\t\t<ul>\n";
responseStream << "\t\t\t\t\t<li><a href=\"";
#line 22 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/groups\"><span class=\"link-title\">Gruppen</span></a></li>\n";
responseStream << "\t\t\t\t\t<li><a href=\"";
#line 23 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/nodes\"><span class=\"link-title\">Node Server</span></a></li>\n";
responseStream << "\t\t\t\t\t<li><a href=\"";
#line 24 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/hedera_account\"><span class=\"link-title\">Hedera Accounts</span></a></li>\n";
responseStream << "\t\t\t\t\t<li><a href=\"";
#line 25 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_large.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/topic\"><span class=\"link-title\">Hedera Topics</span></a></li>\n";
responseStream << "\t\t\t\t</ul>\n";
responseStream << "\t\t\t</div>\n";
responseStream << "\t\t</div>\n";
responseStream << "\t\t<div class=\"content\">";
// end include header_large.cpsp
responseStream << " <div class=\"center-form-single\">\n";
responseStream << " <div class=\"center-form-header\">\n";
responseStream << " <a href=\"";
#line 21 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "\" class=\"center-logo\">\n";
responseStream << " <picture>\n";
responseStream << " <source srcset=\"";
#line 23 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "img/logo_schrift.webp\" type=\"image/webp\">\n";
responseStream << " <source srcset=\"";
#line 24 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "img/logo_schrift.png\" type=\"image/png\">\n";
responseStream << " <img src=\"";
#line 25 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "img/logo_schrift.png\" alt=\"logo\" />\n";
responseStream << " </picture>\n";
responseStream << " </a>\n";
responseStream << " </div>";
// end include header.cpsp
responseStream << "\n";
#line 16 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "<style type=\"text/css\">\n";
responseStream << "\t.center-form-form .input-40 {\n";
responseStream << "\t\tmargin-left:0;\n";
responseStream << "\t\twidth:40%;\n";
responseStream << "\t\tdisplay:inline-block;\n";
responseStream << "\t}\n";
responseStream << "\t\n";
responseStream << "</style>\n";
#line 40 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( getErrorsHtml() );
responseStream << "\n";
responseStream << "<div class=\"content-container info-container\">\n";
responseStream << "\t<h1>Topic Admin Page</h1>\n";
responseStream << "</div>\n";
responseStream << "<div class=\"content-container main-container\">\n";
responseStream << "\t\n";
responseStream << "<div class=\"center-form-container\">\n";
responseStream << "\t<div class=\"center-form-title\">\n";
responseStream << "\t <h3>Ein neues Topic anlegen</h3>\n";
responseStream << "\t</div>\n";
responseStream << "\t<div class=\"center-form-form\">\n";
responseStream << "\t\t<form method=\"POST\" action=\"";
#line 49 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/topic\">\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-auto-renew-account\">Auto Renew Hedera Account</label>\n";
responseStream << "\t\t\t<select name=\"topic-auto-renew-account\" id=\"topic-auto-renew-account\">\n";
responseStream << "\t\t\t\t";
#line 52 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
auto model = (*it)->getModel();
responseStream << "\n";
responseStream << "\t\t\t\t\t<option title=\"";
#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( model->toString() );
responseStream << "\" value=\"";
#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( model->getID() );
responseStream << "\" ";
#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
if(auto_renew_account == model->getID()) { responseStream << "selected=\"selected\"";
#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << ">";
#line 55 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( (*it)->toShortSelectOptionName() );
responseStream << "</option>\n";
responseStream << "\t\t\t\t";
#line 56 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t\t</select>\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-auto-renew-period\">Auto Renew Period in seconds</label>\n";
responseStream << "\t\t\t<div><input class=\"form-control input-40\" id=\"topic-auto-renew-period\" value=\"";
#line 59 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( auto_renew_period );
responseStream << "\" type=\"number\" name=\"topic-auto-renew-period\"/><span style=\"margin-left:8px\" id=\"readable-auto-renew-period\"></span><div>\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-group\">Group</label>\n";
responseStream << "\t\t\t<select class=\"form-control\" name=\"topic-group\" id=\"topic-group\">\t\t\t\n";
responseStream << "\t\t\t\t";
#line 62 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
for(auto it = groups.begin(); it != groups.end(); it++) {
auto group_model = (*it)->getModel(); responseStream << "\n";
responseStream << "\t\t\t\t\t<option title=\"";
#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getDescription() );
responseStream << "\" value=\"";
#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getID() );
responseStream << "\" ";
#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
if(group_id == group_model->getID()) { responseStream << "selected=\"selected\"";
#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << ">";
#line 64 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getName() );
responseStream << "</option>\n";
responseStream << "\t\t\t\t";
#line 65 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t\t</select>\n";
responseStream << "\t\t\t\n";
responseStream << "\t\t\t<input class=\"center-form-submit form-button\" type=\"submit\" name=\"submit\" value=\"";
#line 68 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( gettext("Add Topic") );
responseStream << "\">\n";
responseStream << "\t\t</form>\n";
responseStream << "\t</div>\n";
responseStream << "</div>\n";
// begin include footer.cpsp
responseStream << " <div class=\"center-bottom\">\n";
@ -124,5 +215,18 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "</html>";
// end include footer.cpsp
responseStream << "\n";
responseStream << "<script type=\"text/javascript\" src=\"";
#line 73 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "/js/time_calculations.js\"></script>\n";
responseStream << "<script type=\"text/javascript\">\n";
responseStream << "\tvar input = document.getElementById(\"topic-auto-renew-period\");\n";
responseStream << "\tvar span = document.getElementById(\"readable-auto-renew-period\");\n";
responseStream << "\tspan.innerHTML = getExactTimeDuration(input.value);\n";
responseStream << "\tinput.addEventListener('keyup', function(e) {\n";
responseStream << "\t\tspan.innerHTML = '~ ' + getExactTimeDuration(input.value);\n";
responseStream << "\t});\n";
responseStream << "\t\n";
responseStream << "</script>";
if (_compressResponse) _gzipStream.close();
}

View File

@ -15,16 +15,25 @@ namespace controller {
}
Poco::AutoPtr<CryptoKey> CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user)
Poco::AutoPtr<CryptoKey> CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user, bool saveEncrypted/* = true*/)
{
auto mm = MemoryManager::getInstance();
auto encrypted_priv_key = hederaKeyPair->getCryptedPrivKey(user->getPassword());
MemoryBin* private_key = nullptr;
auto public_key = hederaKeyPair->getPublicKeyCopy();
auto db = new model::table::CryptoKey(encrypted_priv_key, public_key, model::table::KEY_TYPE_ED25519_HEDERA);
model::table::KeyType key_type;
if (saveEncrypted) {
key_type = model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED;
private_key = hederaKeyPair->getCryptedPrivKey(user->getPassword());
}
else {
key_type = model::table::KEY_TYPE_ED25519_HEDERA_CLEAR;
private_key = hederaKeyPair->getPrivateKeyCopy();
}
auto db = new model::table::CryptoKey(private_key, public_key, key_type);
mm->releaseMemory(encrypted_priv_key);
mm->releaseMemory(private_key);
mm->releaseMemory(public_key);
auto cryptoKey = new CryptoKey(db);
@ -63,28 +72,49 @@ namespace controller {
return nullptr;
}
std::unique_ptr<KeyPairHedera> CryptoKey::getKeyPair(Poco::AutoPtr<controller::User> user)
std::unique_ptr<KeyPairHedera> CryptoKey::getKeyPair(Poco::AutoPtr<controller::User> user) const
{
auto model = getModel();
auto password = user->getPassword();
auto mm = MemoryManager::getInstance();
if (!password || !model->hasPrivateKeyEncrypted()) {
printf("[CryptoKey::getKeyPair] return null, password empty or no private key\n");
assert(model);
if (!model->isEncrypted()) {
return getKeyPair();
}
if (!model->hasPrivateKey()) {
printf("[CryptoKey::getKeyPair] return null, no private key\n");
return nullptr;
}
MemoryBin* clearPassword = nullptr;
auto encrypted_private_key = model->getPrivateKeyEncrypted();
auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key);
printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data());
if (password->decrypt(model->getPrivateKeyEncrypted(), &clearPassword) != SecretKeyCryptography::AUTH_DECRYPT_OK) {
auto password = user->getPassword();
auto mm = MemoryManager::getInstance();
if (!password) {
printf("[CryptoKey::getKeyPair] return null, password empty\n");
}
MemoryBin* clearPrivateKey = nullptr;
auto encrypted_private_key = model->getPrivateKey();
//auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key);
//printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data());
if (password->decrypt(model->getPrivateKey(), &clearPrivateKey) != SecretKeyCryptography::AUTH_DECRYPT_OK) {
printf("[CryptoKey::getKeyPair] return null, error decrypting\n");
return nullptr;
}
auto key_pair = std::make_unique<KeyPairHedera>(clearPassword, model->getPublicKey(), model->getPublicKeySize());
mm->releaseMemory(clearPassword);
auto key_pair = std::make_unique<KeyPairHedera>(clearPrivateKey->data(), clearPrivateKey->size(), model->getPublicKey(), model->getPublicKeySize());
mm->releaseMemory(clearPrivateKey);
return key_pair;
}
std::unique_ptr<KeyPairHedera> CryptoKey::getKeyPair() const
{
auto model = getModel();
assert(model);
if (!model->hasPrivateKey() || model->isEncrypted()) {
printf("[CryptoKey::getKeyPair] no private key or encrypted\n");
return nullptr;
}
return std::make_unique<KeyPairHedera>(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize());
}
}

View File

@ -16,7 +16,7 @@ namespace controller {
~CryptoKey();
static Poco::AutoPtr<CryptoKey> create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user);
static Poco::AutoPtr<CryptoKey> create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user, bool saveEncrypted = true);
//! if returned ptr is NULL, dataset not found
static Poco::AutoPtr<CryptoKey> load(int id);
@ -26,8 +26,10 @@ namespace controller {
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
inline Poco::AutoPtr<model::table::CryptoKey> getModel() { return _getModel<model::table::CryptoKey>(); }
inline const model::table::CryptoKey* getModel() const { return _getModel<model::table::CryptoKey>(); }
std::unique_ptr<KeyPairHedera> getKeyPair(Poco::AutoPtr<controller::User> user);
std::unique_ptr<KeyPairHedera> getKeyPair(Poco::AutoPtr<controller::User> user) const;
std::unique_ptr<KeyPairHedera> getKeyPair() const;
protected:

View File

@ -73,7 +73,7 @@ namespace controller {
return resultVector;
}
bool HederaAccount::updateBalanceFromHedera(Poco::AutoPtr<controller::User> user, NotificationList* errorReceiver/* = nullptr*/)
bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr<controller::User> user, NotificationList* errorReceiver/* = nullptr*/)
{
static const char* functionName = "HederaAccount::updateBalanceFromHedera";
@ -132,5 +132,15 @@ namespace controller {
return false;
}
std::string HederaAccount::toShortSelectOptionName()
{
std::stringstream ss;
auto model = getModel();
ss << model::table::HederaAccount::hederaNetworkTypeToString((model::table::HederaNetworkType)model->getNetworkType()) << " ";
ss << mHederaID->getModel()->toString() << " " << ((double)model->getBalance() / 100000000.0) << " Hbar";
return ss.str();
}
}

View File

@ -22,12 +22,14 @@ namespace controller {
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
std::string HederaAccount::toShortSelectOptionName();
inline Poco::AutoPtr<model::table::HederaAccount> getModel() { return _getModel<model::table::HederaAccount>(); }
inline void setHederaId(Poco::AutoPtr<controller::HederaId> hederaId) { mHederaID = hederaId; }
inline Poco::AutoPtr<controller::HederaId> getHederaId() { return mHederaID; }
bool updateBalanceFromHedera(Poco::AutoPtr<controller::User> user, NotificationList* errorReceiver = nullptr);
bool hederaAccountGetBalance(Poco::AutoPtr<controller::User> user, NotificationList* errorReceiver = nullptr);
protected:
HederaAccount(model::table::HederaAccount* dbModel);

View File

@ -59,6 +59,18 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::h
return HEDERA_REQUEST_RETURN_OK;
}
HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, model::hedera::Response* response)
{
auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials());
grpc::ClientContext context;
std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() +
std::chrono::milliseconds(5000);
context.set_deadline(deadline);
return HEDERA_REQUEST_RETURN_OK;
}
#include "Poco/JSON/Object.h"
#include "../lib/JsonRequest.h"

View File

@ -31,6 +31,7 @@ public:
~HederaRequest();
HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0);
HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response);
//! for testing, didn't work server say invalid json :/
HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query);

View File

@ -0,0 +1,26 @@
#include "HederaTopic.h"
#include "../model/hedera/Transaction.h"
namespace controller {
HederaTopic::HederaTopic(model::table::HederaTopic* dbModel)
{
mDBModel = dbModel;
}
HederaTopic::~HederaTopic()
{
}
Poco::AutoPtr<HederaTopic> HederaTopic::create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId)
{
auto db = new model::table::HederaTopic(name, autoRenewAccountId, autoRenewPeriod, groupId);
auto hedera_topic = new HederaTopic(db);
return Poco::AutoPtr<HederaTopic>(hedera_topic);
}
Poco::UInt64 HederaTopic::hederaCreateTopic()
{
}
}

View File

@ -0,0 +1,38 @@
#ifndef __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H
#define __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H
/*!
*
* \author: Dario Rekowski
*
* \date: 03.09.2020
*
* \brief: Class for Hedera Topic, connct db table with hedera object
*
*/
#include "TableControllerBase.h"
#include "../model/table/HederaTopic.h"
namespace controller {
class HederaTopic : public TableControllerBase
{
public:
~HederaTopic();
static Poco::AutoPtr<HederaTopic> create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId);
//! \brief hedera call to create a hedera topic
Poco::UInt64 hederaCreateTopic();
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
inline Poco::AutoPtr<model::table::HederaTopic> getModel() { return _getModel<model::table::HederaTopic>(); }
protected:
HederaTopic(model::table::HederaTopic* dbModel);
};
#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H

View File

@ -45,17 +45,25 @@ int main(int argc, char** argv)
printf("[Gradido_LoginServer::main] error loading mnemonic Word List");
return -2;
}
printf("[Gradido_LoginServer::main] mnemonic word lists loaded!\n");
if (!ImportantTests::passphraseGenerationAndTransformation()) {
printf("test passphrase generation and transformation failed\n");
return -3;
}
printf("[Gradido_LoginServer::main] passed important tests\n");
grpc_init();
Gradido_LoginServer app;
auto result = app.run(argc, argv);
grpc_shutdown();
return result;
try {
auto result = app.run(argc, argv);
grpc_shutdown();
return result;
}
catch (Poco::Exception& ex) {
printf("[Gradido_LoginServer::main] exception by starting server: %s\n", ex.displayText().data());
}
return -1;
}
#endif

View File

@ -0,0 +1,45 @@
#include "ConsensusCreateTopic.h"
namespace model {
namespace hedera {
ConsensusCreateTopic::ConsensusCreateTopic(Poco::AutoPtr<controller::HederaId> autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod)
: mProtoCreateTopic(nullptr)
{
mProtoCreateTopic = new proto::ConsensusCreateTopicTransactionBody;
auto auto_renew_period = mProtoCreateTopic->mutable_autorenewperiod();
auto_renew_period->set_seconds(autoRenewPeriod);
auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount();
autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account);
}
ConsensusCreateTopic::~ConsensusCreateTopic()
{
if (mProtoCreateTopic) {
delete mProtoCreateTopic;
mProtoCreateTopic = nullptr;
}
}
void ConsensusCreateTopic::setAdminKey(const MemoryBin* adminPublicKey)
{
auto admin_key = mProtoCreateTopic->mutable_adminkey();
auto admin_key_string = admin_key->mutable_ed25519();
*admin_key_string = std::string((const char)*adminPublicKey, adminPublicKey->size());
}
void ConsensusCreateTopic::setSubmitKey(const MemoryBin* submitPublicKey)
{
auto submit_key = mProtoCreateTopic->mutable_submitkey();
auto submit_key_string = submit_key->mutable_ed25519();
*submit_key_string = std::string((const char)*submitPublicKey, submitPublicKey->size());
}
bool ConsensusCreateTopic::validate()
{
if (mProtoCreateTopic->autorenewperiod().seconds() > 86400 && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) {
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,31 @@
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
#include "../../proto/hedera/ConsensusCreateTopic.pb.h"
#include "../../SingletonManager/MemoryManager.h"
#include "../../controller/HederaId.h"
namespace model {
namespace hedera {
class ConsensusCreateTopic
{
public:
ConsensusCreateTopic(Poco::AutoPtr<controller::HederaId> autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod);
~ConsensusCreateTopic();
inline void setMemo(const std::string& memo) { mProtoCreateTopic->set_memo(memo); }
void setAdminKey(const MemoryBin* adminPublicKey);
void setSubmitKey(const MemoryBin* submitPublicKey);
bool validate();
inline proto::ConsensusCreateTopicTransactionBody* getProtoTransactionBody() { return mProtoCreateTopic; }
inline void resetPointer() { mProtoCreateTopic = nullptr; }
protected:
proto::ConsensusCreateTopicTransactionBody* mProtoCreateTopic;
};
}
}
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H

View File

@ -0,0 +1,16 @@
#include "CryptoCreateTransaction.h"
namespace model {
namespace hedera {
CryptoCreateTransaction::CryptoCreateTransaction()
{
}
CryptoCreateTransaction::~CryptoCreateTransaction()
{
}
}
}

View File

@ -0,0 +1,23 @@
#ifndef __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
#define __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
#include "../../proto/hedera/CryptoCreate.pb.h"
namespace model {
namespace hedera {
class CryptoCreateTransaction
{
public:
CryptoCreateTransaction();
~CryptoCreateTransaction();
protected:
proto::CryptoCreateTransactionBody* mCryptoCreateBody;
};
}
}
#endif //__GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H

View File

@ -9,8 +9,8 @@
namespace model {
namespace hedera {
Query::Query(const controller::NodeServerConnection& connection)
: mConnection(connection), mTransactionBody(nullptr)
Query::Query()
: mTransactionBody(nullptr)
{
}
@ -27,7 +27,7 @@ namespace model {
assert(!accountId.isNull() && accountId->getModel());
auto query = new Query(connection);
auto query = new Query;
auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance();
accountId->copyToProtoAccountId(get_account_balance->mutable_accountid());
auto query_header = get_account_balance->mutable_header();

View File

@ -26,15 +26,14 @@ namespace model {
void setResponseType(proto::ResponseType type);
proto::ResponseType getResponseType();
void setFee(Poco::UInt64 fee);
inline const proto::Query* getProtoQuery() const { return &mQueryProto; }
inline std::string getConnectionString() const { return mConnection.getUriWithPort(); }
inline std::string getConnectionString() const { return mTransactionBody->getConnectionString(); }
protected:
Query(const controller::NodeServerConnection& connection);
Query();
proto::Query mQueryProto;
TransactionBody* mTransactionBody;
controller::NodeServerConnection mConnection;
};
}
}

View File

@ -19,6 +19,7 @@ namespace model {
bool Transaction::sign(std::unique_ptr<KeyPairHedera> keyPairHedera, const TransactionBody* transactionBody)
{
auto mm = MemoryManager::getInstance();
mConnection = transactionBody->getConnection();
auto transaction_body_proto = transactionBody->getProtoTransactionBody();
auto body_bytes = transaction_body_proto->SerializeAsString();
mTransaction->set_bodybytes(body_bytes.data());

View File

@ -25,11 +25,12 @@ namespace model {
bool sign(std::unique_ptr<KeyPairHedera> keyPairHedera, const TransactionBody* transactionBody);
inline proto::Transaction* getTransaction() { return mTransaction; }
inline std::string getConnectionString() const { return mConnection.getUriWithPort(); }
void resetPointer() { mTransaction = nullptr; }
protected:
proto::Transaction* mTransaction;
controller::NodeServerConnection mConnection;
};
}
}

View File

@ -3,6 +3,7 @@
namespace model {
namespace hedera {
TransactionBody::TransactionBody(Poco::AutoPtr<controller::HederaId> operatorAccountId, const controller::NodeServerConnection& connection)
: mConnection(connection)
{
connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid());
auto transaction_id = mTransactionBody.mutable_transactionid();
@ -29,10 +30,24 @@ namespace model {
return false;
}
bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction)
{
if (consensusCreateTopicTransaction.validate()) {
mTransactionBody.set_allocated_consensuscreatetopic(consensusCreateTopicTransaction.getProtoTransactionBody());
consensusCreateTopicTransaction.resetPointer();
return true;
}
return false;
}
void TransactionBody::setMemo(const std::string& memo)
{
mTransactionBody.set_memo(memo);
}
void TransactionBody::setFee(Poco::UInt64 fee)
{
mTransactionBody.set_transactionfee(fee);
}
void TransactionBody::updateTimestamp()
{

View File

@ -13,6 +13,7 @@
#include "../../proto/hedera/TransactionBody.pb.h"
#include "../../controller/NodeServer.h"
#include "CryptoTransferTransaction.h"
#include "ConsensusCreateTopic.h"
namespace model {
namespace hedera {
@ -23,14 +24,20 @@ namespace model {
~TransactionBody();
void setMemo(const std::string& memo);
void setFee(Poco::UInt64 fee);
bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction);
bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction);
//bool
inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; }
inline std::string getConnectionString() const { return mConnection.getUriWithPort(); }
inline controller::NodeServerConnection getConnection() const { return mConnection; }
protected:
void updateTimestamp();
proto::TransactionBody mTransactionBody;
controller::NodeServerConnection mConnection;
};
}
}

View File

@ -43,12 +43,33 @@ namespace model {
const char* CryptoKey::typeToString(KeyType type)
{
switch (type) {
case KEY_TYPE_ED25519_SODIUM: return "ed25519 ref10";
case KEY_TYPE_ED25519_HEDERA: return "sodium ed22519";
case KEY_TYPE_ED25519_SODIUM_ENCRYPTED: return "ed25519 sodium encrypted";
case KEY_TYPE_ED25519_HEDERA_ENCRYPTED: return "ed22519 for hedera encrypted";
case KEY_TYPE_ED25519_SODIUM_CLEAR: return "ed25519 sodium clear";
case KEY_TYPE_ED25519_HEDERA_CLEAR: return "ed25519 hedera clear";
}
return "<unknown type>";
}
bool CryptoKey::hasPrivateKeyEncrypted() const
{
const KeyType type = (KeyType)(mKeyType);
if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED || type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) {
return !mPrivateKey.isNull();
}
return false;
}
bool CryptoKey::isEncrypted() const
{
const KeyType type = (KeyType)(mKeyType);
if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED ||
type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) {
return true;
}
return false;
}
Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
{
Poco::Data::Statement select(session);

View File

@ -8,8 +8,10 @@ namespace model {
namespace table {
enum KeyType {
KEY_TYPE_ED25519_SODIUM = 0,
KEY_TYPE_ED25519_HEDERA = 1,
KEY_TYPE_ED25519_SODIUM_ENCRYPTED = 0,
KEY_TYPE_ED25519_HEDERA_ENCRYPTED = 1,
KEY_TYPE_ED25519_SODIUM_CLEAR = 2,
KEY_TYPE_ED25519_HEDERA_CLEAR = 3,
KEY_TYPE_COUNT
};
@ -27,8 +29,10 @@ namespace model {
inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); }
size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); }
inline bool hasPrivateKeyEncrypted() const { return !mPrivateKey.isNull(); }
inline const std::vector<unsigned char>& getPrivateKeyEncrypted() const { return mPrivateKey.value().content(); }
bool hasPrivateKeyEncrypted() const;
bool isEncrypted() const;
inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); }
inline const std::vector<unsigned char>& getPrivateKey() const { return mPrivateKey.value().content(); }
static const char* typeToString(KeyType type);
protected:

View File

@ -44,6 +44,7 @@ namespace model {
return ss.str();
}
const char* HederaAccount::hederaNetworkTypeToString(HederaNetworkType type)
{
switch (type) {

View File

@ -28,6 +28,7 @@ namespace model {
// generic db operations
const char* getTableName() const { return "hedera_accounts"; }
std::string toString();
static const char* hederaNetworkTypeToString(HederaNetworkType type);
static NodeServerType networkTypeToNodeServerType(HederaNetworkType type);

View File

@ -5,6 +5,14 @@ using namespace Poco::Data::Keywords;
namespace model {
namespace table {
HederaTopic::HederaTopic()
: mTopicHederaId(0), mAutoRenewAccountHederaId(0), mAutoRenewPeriod(0), mGroupId(0), mAdminKeyId(0), mSubmitKeyId(0),mSequenceNumber(0)
{
}
HederaTopic::HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId)
: mTopicHederaId(0), mName(name), mAutoRenewAccountHederaId(autoRenewAccountId), mAutoRenewPeriod(autoRenewAccountId), mGroupId(groupId),
mAdminKeyId(0), mSubmitKeyId(0), mSequenceNumber(0)
{
}
@ -18,6 +26,7 @@ namespace model {
{
std::stringstream ss;
ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl;
ss << "Name: " << mName << std::endl;
ss << "Auto Renew Account Hedera id: " << std::to_string(mAutoRenewAccountHederaId) << std::endl;
ss << "Auto Renew Period: " << std::to_string(mAutoRenewPeriod) << " seconds" << std::endl;
ss << "Group id: " << std::to_string(mGroupId) << std::endl;
@ -33,10 +42,10 @@ namespace model {
{
Poco::Data::Statement select(session);
select << "SELECT id, topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period, "
select << "SELECT id, topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period, "
<< "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName()
<< " where " << fieldName << " = ?"
, into(mID), into(mTopicHederaId), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod)
, into(mID), into(mTopicHederaId), into(mName), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod)
, into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated);
return select;
@ -57,9 +66,9 @@ namespace model {
Poco::Data::Statement insert(session);
lock();
insert << "INSERT INTO " << getTableName()
<< " (topic_hedera_id, auto_renew_account_hedera_id, auto_renew_period,"
<< " (topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period,"
<< " group_id, admin_key_id, submit_key_id, current_timeout, sequence_number) VALUES(?,?,?,?,?,?,?,?)"
, use(mTopicHederaId), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod)
, use(mTopicHederaId), use(mName), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod)
, use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber), use(mUpdated);
unlock();
return insert;

View File

@ -10,12 +10,25 @@ namespace model {
{
public:
HederaTopic();
HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId);
~HederaTopic();
// generic db operations
const char* getTableName() const { return "hedera_topics"; }
std::string toString();
inline Poco::UInt32 getTopicHederaId() const { return mTopicHederaId; }
inline std::string getName() const { return mName; }
inline Poco::UInt32 getAutoRenewAccountId() const { return mAutoRenewAccountHederaId; }
inline Poco::UInt32 getAutoRenewPeriod() const { return mAutoRenewPeriod; }
inline Poco::UInt32 getGroupId() const { return mGroupId;}
inline Poco::DateTime getCurrentTimoout() const { return mCurrentTimeout; }
inline Poco::UInt64 getSequenceNumber() const { return mSequenceNumber; }
inline Poco::DateTime getUpdated() const { return mUpdated; }
inline void setTopicHederaID(Poco::UInt32 topidHederaId) { mTopicHederaId = topidHederaId;}
inline void setSequeceNumber(Poco::UInt64 sequenceNumber) { mSequenceNumber = sequenceNumber; }
inline void setCurrentTimeout(Poco::DateTime currentTimeOut) { mCurrentTimeout = currentTimeOut; }
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
@ -23,6 +36,7 @@ namespace model {
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
Poco::UInt32 mTopicHederaId;
std::string mName;
Poco::UInt32 mAutoRenewAccountHederaId;
// in seconds
Poco::UInt32 mAutoRenewPeriod;

View File

@ -49,7 +49,7 @@
addError(new Error("Action Update Balance", "hedera id not found"));
} else {
hedera_time.reset();
hedera_account[0]->updateBalanceFromHedera(user, this);
hedera_account[0]->hederaAccountGetBalance(user, this);
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
}
}
@ -204,6 +204,7 @@
<% } %>
</select>
<input class="center-form-submit form-button" type="submit" name="submit" value="<%= gettext("Add Account") %>">
</form>
</form>
</div>
</div>
<%@ include file="footer.cpsp" %>

View File

@ -5,19 +5,123 @@
<%@ page ctorArg="Session*" %>
<%@ header include="SessionHTTPRequestHandler.h" %>
<%!
#include "../controller/HederaAccount.h"
#include "../controller/Group.h"
#include "../SingletonManager/SessionManager.h"
#include "../ServerConfig.h"
#include "../lib/DataTypeConverter.h"
%>
<%%
const char* pageName = "Topic";
auto user = mSession->getNewUser();
auto sm = SessionManager::getInstance();
std::string name = "";
int auto_renew_account = 0;
int auto_renew_period = 604800; // 7 Tage
int group_id = 0;
if(!form.empty()) {
name = form.get("topic-name", "");
auto auto_renew_account_string = form.get("topic-auto-renew-account", "0");
auto auto_renew_period_string = form.get("topic-auto-renew-period", "604800");
auto group_id_string = form.get("topic-group", "-1");
if(name != "" && !sm->isValid(name, VALIDATE_NAME)) {
addError(new Error("Topic", "Name not valid, at least 3 Character"));
}
if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) {
addError(new Error("Topic", "auto renew account id not an integer"));
} else {
if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) {
addError(new Error("Int convert error", "Error converting auto renew account id to int"));
}
}
if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) {
addError(new Error("Topic", "auto renew period not an integer"));
} else {
if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) {
addError(new Error("Int convert error", "Error converting auto renew period to int"));
}
}
%><%@ include file="header_large.cpsp" %>
if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) {
addError(new Error("Topic", "group_id not an integer"));
} else {
if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
addError(new Error("Int convert error", "Error converting group_id to int"));
}
}
}
auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID());
auto groups = controller::Group::listAll();
std::map<int, int> group_indices;
int count = 0;
for(auto it = groups.begin(); it != groups.end(); it++) {
group_indices.insert(std::pair<int, int>((*it)->getModel()->getID(), count));
count++;
}
%><%@ include file="header.cpsp" %>
<style type="text/css">
.center-form-form .input-40 {
margin-left:0;
width:40%;
display:inline-block;
}
</style>
<%= getErrorsHtml() %>
<div class="content-container info-container">
<h1>Topic Admin Page</h1>
</div>
<div class="content-container main-container">
<div class="center-form-container">
<div class="center-form-title">
<h3>Ein neues Topic anlegen</h3>
</div>
<div class="center-form-form">
<form method="POST" action="<%= ServerConfig::g_serverPath %>/topic">
<label class="form-label" for="topic-name">Name</label>
<input type="text" class="form-control" id="topic-name" name="topic-name" value="<%= name %>">
<label class="form-label" for="topic-auto-renew-account">Auto Renew Hedera Account</label>
<select name="topic-auto-renew-account" id="topic-auto-renew-account">
<% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
auto model = (*it)->getModel();
%>
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(auto_renew_account == model->getID()) {%>selected="selected"<% } %>><%= (*it)->toShortSelectOptionName() %></option>
<% } %>
</select>
<label class="form-label" for="topic-auto-renew-period">Auto Renew Period in seconds</label>
<div><input class="form-control input-40" id="topic-auto-renew-period" value="<%= auto_renew_period %>" type="number" name="topic-auto-renew-period"/><span style="margin-left:8px" id="readable-auto-renew-period"></span><div>
<label class="form-label" for="topic-group">Group</label>
<select class="form-control" name="topic-group" id="topic-group">
<option value="-1">Keine Gruppe</option>
<% for(auto it = groups.begin(); it != groups.end(); it++) {
auto group_model = (*it)->getModel(); %>
<option title="<%= group_model->getDescription() %>" value="<%= group_model->getID() %>" <% if(group_id == group_model->getID()) {%>selected="selected"<% } %>><%= group_model->getName() %></option>
<% } %>
</select>
<input class="center-form-submit form-button" type="submit" name="submit" value="<%= gettext("Add Topic") %>">
</form>
</div>
</div>
<%@ include file="footer.cpsp" %>
<script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/time_calculations.js"></script>
<script type="text/javascript">
var input = document.getElementById("topic-auto-renew-period");
var span = document.getElementById("readable-auto-renew-period");
span.innerHTML = '~ ' + getExactTimeDuration(input.value);
input.addEventListener('keyup', function(e) {
span.innerHTML = '~ ' + getExactTimeDuration(input.value);
});
</script>