From d1f27a90d9d1257d2c0c7feeb8483f1cd93c2846 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sun, 12 Mar 2017 16:56:56 +0800 Subject: [PATCH] refactoring of YourMoneroRequests::login started --- html/js/controllers/login.js | 11 +++- main.cpp | 2 - sql/openmonero.sql | 13 +++-- src/MySqlAccounts.cpp | 13 ++--- src/MySqlAccounts.h | 4 +- src/YourMoneroRequests.cpp | 107 +++++++++++++++++++++++++---------- src/ssqlses.h | 7 ++- src/tools.cpp | 9 +++ src/tools.h | 3 + 9 files changed, 117 insertions(+), 52 deletions(-) diff --git a/html/js/controllers/login.js b/html/js/controllers/login.js index ee20e1f..c41af67 100755 --- a/html/js/controllers/login.js +++ b/html/js/controllers/login.js @@ -126,7 +126,16 @@ thinwalletCtrls.controller("LoginCtrl", function($scope, $location, AccountServi $scope.login_keys = function(address, view_key, spend_key) { $scope.error = ''; AccountService.login(address, view_key, spend_key, undefined, false) - .then(function() { + .then(function(data) + { + if (data.status === "error") + { + $scope.status = ""; + $scope.submitting = false; + $scope.error = "Something unexpected occurred when submitting your transaction: " + data.error; + return; + } + ModalService.hide('login'); $location.path("/overview"); if (AccountService.wasAccountImported()) { diff --git a/main.cpp b/main.cpp index e5464f7..9116de7 100644 --- a/main.cpp +++ b/main.cpp @@ -145,8 +145,6 @@ if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) xmreg::CurrentBlockchainStatus::start_monitor_blockchain_thread(); - - // create REST JSON API services // Open Monero frontend url. Frontend url must match this value in diff --git a/sql/openmonero.sql b/sql/openmonero.sql index e44ed18..ad96f61 100644 --- a/sql/openmonero.sql +++ b/sql/openmonero.sql @@ -3,7 +3,7 @@ -- https://www.phpmyadmin.net/ -- -- Host: localhost --- Generation Time: Feb 21, 2017 at 02:37 AM +-- Generation Time: Mar 12, 2017 at 08:38 AM -- Server version: 10.1.21-MariaDB -- PHP Version: 7.1.2 @@ -32,6 +32,7 @@ DROP TABLE IF EXISTS `Accounts`; CREATE TABLE `Accounts` ( `id` bigint(10) UNSIGNED NOT NULL, `address` varchar(95) NOT NULL, + `viewkey_hash` char(64) NOT NULL, `scanned_block_height` int(10) UNSIGNED NOT NULL DEFAULT '0', `start_height` int(10) UNSIGNED NOT NULL DEFAULT '0', `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -174,27 +175,27 @@ ALTER TABLE `Transactions` -- AUTO_INCREMENT for table `Accounts` -- ALTER TABLE `Accounts` - MODIFY `id` bigint(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9; + MODIFY `id` bigint(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=55; -- -- AUTO_INCREMENT for table `Inputs` -- ALTER TABLE `Inputs` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=449; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1738; -- -- AUTO_INCREMENT for table `Outputs` -- ALTER TABLE `Outputs` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11206; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4373; -- -- AUTO_INCREMENT for table `Payments` -- ALTER TABLE `Payments` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11; -- -- AUTO_INCREMENT for table `Transactions` -- ALTER TABLE `Transactions` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3145; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3702; -- -- Constraints for dumped tables -- diff --git a/src/MySqlAccounts.cpp b/src/MySqlAccounts.cpp index ed52bc9..2028869 100644 --- a/src/MySqlAccounts.cpp +++ b/src/MySqlAccounts.cpp @@ -645,14 +645,6 @@ bool MySqlAccounts::select(const string& address, XmrAccount& account) { - if (!conn->connect()) - { - cerr << __FUNCTION__ << ":" << __LINE__ - << " failed connecting to mysql" - << endl; - return false; - } - Query query = conn->query(XmrAccount::SELECT_STMT); query.parse(); @@ -716,7 +708,9 @@ MySqlAccounts::select(const int64_t& acc_id, XmrAccount& account) } uint64_t -MySqlAccounts::insert(const string& address, const uint64_t& current_blkchain_height) +MySqlAccounts::insert(const string& address, + const string& viewkey_hash, + const uint64_t& current_blkchain_height) { Query query = conn->query(XmrAccount::INSERT_STMT); @@ -733,6 +727,7 @@ MySqlAccounts::insert(const string& address, const uint64_t& current_blkchain_he //cout << "insert address: " << address << endl; SimpleResult sr = query.execute(address, + viewkey_hash, current_blkchain_height, current_blkchain_height); diff --git a/src/MySqlAccounts.h b/src/MySqlAccounts.h index 64d9fab..f08ea12 100644 --- a/src/MySqlAccounts.h +++ b/src/MySqlAccounts.h @@ -175,7 +175,9 @@ public: select(const int64_t& acc_id, XmrAccount& account); uint64_t - insert(const string& address, const uint64_t& current_blkchain_height = 0); + insert(const string& address, + const string& viewkey_hash, + const uint64_t& current_blkchain_height = 0); uint64_t insert_tx(const XmrTransaction& tx_data); diff --git a/src/YourMoneroRequests.cpp b/src/YourMoneroRequests.cpp index 5cc38dd..9bc109b 100644 --- a/src/YourMoneroRequests.cpp +++ b/src/YourMoneroRequests.cpp @@ -36,21 +36,88 @@ YourMoneroRequests::YourMoneroRequests(shared_ptr _acc): void YourMoneroRequests::login(const shared_ptr session, const Bytes & body) { - json j_request = body_to_json(body); + json j_request; - string xmr_address = j_request["address"]; + json j_response; + + string xmr_address; + string view_key; + + try + { + j_request = body_to_json(body); + + xmr_address = j_request["address"]; + view_key = j_request["view_key"]; + } + catch (std::exception& e) + { + cerr << "login: cant parse json: " << e.what() << endl; + + j_response["status"] = "error"; + j_response["reason"] = "address and/or viewkey not provided"; + + string response_body = j_response.dump(); + + auto response_headers = make_headers({{"Content-Length", to_string(response_body.size())}}); + + session->close( OK, response_body, response_headers); + + return; + } + + // make hash of the submited viewkey. we only store + // hash of viewkey in database, not acctual viewkey. + string viewkey_hash = make_hash(view_key); // a placeholder for exciting or new account data XmrAccount acc; uint64_t acc_id {0}; - json j_response; // select this account if its existing one if (xmr_accounts->select(xmr_address, acc)) { - j_response = {{"new_address", false}}; + // we got accunt from the database. we double check + // if hsah of provided viewkey by the frontend, matches + // what we have in database. + + if (viewkey_hash == acc.viewkey_hash) + { + acc.viewkey = j_request["view_key"]; + + // so we have an account now. Either existing or + // newly created. Thus, we can start a tread + // which will scan for transactions belonging to + // that account, using its address and view key. + // the thread will scan the blockchain for txs belonging + // to that account and updated mysql database whenever it + // will find something. + // + // The other client (i.e., a webbrowser) will query other functions to retrieve + // any belonging transactions in a loop. Thus the thread does not need + // to do anything except looking for tx and updating mysql + // with relative tx information + + if (CurrentBlockchainStatus::start_tx_search_thread(acc)) + { + cout << "Search thread started" << endl; + j_response["status"] = "success"; + j_response["new_address"] = false; + } + else + { + j_response["status"] = "error"; + j_response["reason"] = "Failed created search thread for this account"; + } + + } + else + { + j_response["status"] = "error"; + j_response["reason"] = "Viewkey provided is incorrect"; + } } else { @@ -63,41 +130,19 @@ YourMoneroRequests::login(const shared_ptr session, const Bytes & body) // make it 1 block lower than current, just in case. // this variable will be our using to initialize // `canned_block_height` in mysql Accounts table. - if ((acc_id = xmr_accounts->insert(xmr_address, get_current_blockchain_height())) != 0) + if ((acc_id = xmr_accounts->insert(xmr_address, + viewkey_hash, + get_current_blockchain_height())) != 0) { // select newly created account if (xmr_accounts->select(acc_id, acc)) { - j_response = {{"new_address", true}}; + j_response["status"] = "success"; + j_response["new_address"] = false; } } } - acc.viewkey = j_request["view_key"]; - - // so we have an account now. Either existing or - // newly created. Thus, we can start a tread - // which will scan for transactions belonging to - // that account, using its address and view key. - // the thread will scan the blockchain for txs belonging - // to that account and updated mysql database whenever it - // will find something. - // - // The other client (i.e., a webbrowser) will query other functions to retrieve - // any belonging transactions in a loop. Thus the thread does not need - // to do anything except looking for tx and updating mysql - // with relative tx information - - if (CurrentBlockchainStatus::start_tx_search_thread(acc)) - { - cout << "Search thread started" << endl; - j_response["status"] = "OK"; - } - else - { - j_response["status"] = "error"; - j_response["reason"] = "Failed created search thread for this account"; - } string response_body = j_response.dump(); diff --git a/src/ssqlses.h b/src/ssqlses.h index 10d78ae..fdc4b92 100644 --- a/src/ssqlses.h +++ b/src/ssqlses.h @@ -18,9 +18,10 @@ using namespace std; using namespace nlohmann; using namespace mysqlpp; -sql_create_6(Accounts, 1, 2, +sql_create_7(Accounts, 1, 2, sql_bigint_unsigned, id, sql_varchar , address, + sql_char , viewkey_hash, sql_bigint_unsigned, scanned_block_height, sql_bigint_unsigned, start_height, sql_timestamp , created, @@ -39,7 +40,9 @@ struct XmrAccount : public Accounts )"; static constexpr const char* INSERT_STMT = R"( - INSERT INTO `Accounts` (`address`, `start_height`, `scanned_block_height`) VALUES (%0q, %1q , %2q); + INSERT INTO `Accounts` (`address`, `viewkey_hash`,`start_height`, `scanned_block_height`) + VALUES + (%0q, %1q, %2q, %3q); )"; diff --git a/src/tools.cpp b/src/tools.cpp index 5bf5cdb..104d368 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -1301,5 +1301,14 @@ get_current_time(const char* format) return date::format(format, current_time); } +string +make_hash(const string& in_str) +{ + crypto::hash vk_hash; + crypto::cn_fast_hash(in_str.c_str(), in_str.length(), vk_hash); + return pod_to_hex(vk_hash); +} + + } diff --git a/src/tools.h b/src/tools.h index 1da4a7d..433efc1 100644 --- a/src/tools.h +++ b/src/tools.h @@ -283,6 +283,9 @@ get_human_readable_timestamp(uint64_t ts); string get_current_time(const char* format = "%a, %d %b %Y %H:%M:%S %Z"); +string +make_hash(const string& in_str); + } #endif //XMREG01_TOOLS_H