Merge pull request #237 from larteyoh/backup

move wallet member to user class
pull/245/head
larteyoh 3 months ago committed by GitHub
commit 8f093bbf5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -338,6 +338,13 @@ int neroshop::Node::set(const std::string& key, const std::string& value) {
if(rater_id != current_json["rater_id"].get<std::string>()) { std::cerr << "Rater ID mismatch\n"; return false; } // rater_id is immutable
}
// Make sure the signature has been updated
if (json.contains("signature")) {
assert(json["signature"].is_string());
std::string signature = json["signature"].get<std::string>();
if(signature == current_json["signature"].get<std::string>()) { std::cerr << "Signature is outdated\n"; return false; }
}
// Compare dates of new data and old (pre-existing) data - untested
if(json.contains("last_updated")) {
assert(json["last_updated"].is_string());

@ -461,7 +461,7 @@ std::pair<std::string, std::string> neroshop::Serializer::serialize(const User&
std::string key = neroshop_crypto::sha3_256(value);
// Data verification tests
#ifdef NEROSHOP_DEBUG
#ifdef NEROSHOP_DEBUG0
auto result = seller->get_wallet()->verify_message(user_id, signature);
std::cout << "\033[1mverified: " << (result == 1 ? "\033[32mpass" : "\033[91mfail") << "\033[0m\n";
assert(result == true);

@ -18,7 +18,7 @@
#include <cmath> // floor
#include <random>
neroshop::Seller::Seller() : wallet(nullptr)
neroshop::Seller::Seller()
{}
////////////////////
////////////////////
@ -30,8 +30,6 @@ neroshop::Seller::Seller(const std::string& name) : Seller() {
neroshop::Seller::~Seller() {
// clear customer orders
customer_order_list.clear(); // will reset (delete) all customer orders
// destroy wallet
if(wallet.get()) wallet.reset();
#ifdef NEROSHOP_DEBUG
std::cout << "seller deleted\n";
#endif
@ -137,16 +135,16 @@ void neroshop::Seller::delist_item(const std::string& listing_key) {
}
// Verify the signature
std::string listing_id = value_obj["id"].get<std::string>();
std::string signature = value_obj["signature"].get<std::string>();
bool self_verified = wallet->verify_message(listing_id, signature);
std::string old_signature = value_obj["signature"].get<std::string>();
bool self_verified = wallet->verify_message(listing_id, old_signature);
if(!self_verified) { neroshop::print("Data verification failed."); return; }
// Might be a good idea to set the stock quantity to zero beforehand or nah?
////value_obj["quantity"] = 0;
// Finally, set the expiration date
value_obj["expiration_date"] = neroshop::timestamp::get_current_utc_timestamp();//value_obj["valid_until"] = neroshop::timestamp::get_current_utc_timestamp();
// Re-sign to reflect the modification
std::string new_signature = wallet->sign_message(listing_id, monero_message_signature_type::SIGN_WITH_SPEND_KEY);
value_obj["signature"] = new_signature;
std::string signature = wallet->sign_message(listing_id, monero_message_signature_type::SIGN_WITH_SPEND_KEY);
value_obj["signature"] = signature;
// Send set request containing the updated value with the same key as before
std::string modified_value = value_obj.dump();
std::string response;
@ -350,16 +348,16 @@ void neroshop::Seller::set_stock_quantity(const std::string& listing_key, int qu
}
// Verify the signature
std::string listing_id = value_obj["id"].get<std::string>();
std::string signature = value_obj["signature"].get<std::string>();
bool self_verified = wallet->verify_message(listing_id, signature);
std::string old_signature = value_obj["signature"].get<std::string>();
bool self_verified = wallet->verify_message(listing_id, old_signature);
if(!self_verified) { neroshop::print("Data verification failed."); return; }
// Finally, modify the quantity
value_obj["quantity"] = quantity;
// Add a last_modified or last_updated field so nodes can compare dates and choose the most recent listing
value_obj["last_updated"] = neroshop::timestamp::get_current_utc_timestamp();
// Re-sign to reflect the modification
std::string new_signature = wallet->sign_message(listing_id, monero_message_signature_type::SIGN_WITH_SPEND_KEY);
value_obj["signature"] = new_signature;
std::string signature = wallet->sign_message(listing_id, monero_message_signature_type::SIGN_WITH_SPEND_KEY);
value_obj["signature"] = signature;
// Send set request containing the updated value with the same key as before
std::string modified_value = value_obj.dump();
std::string response;
@ -372,12 +370,6 @@ void neroshop::Seller::set_stock_quantity(const std::string& listing_key, int qu
////////////////////
////////////////////
////////////////////
// setters - wallet-related stuff
////////////////////
void neroshop::Seller::set_wallet(const neroshop::Wallet& wallet) {
std::unique_ptr<neroshop::Wallet> seller_wallet(&const_cast<neroshop::Wallet&>(wallet));
this->wallet = std::move(seller_wallet); // unique pointers cannot be copied, but can only be moved // "std::unique_ptr::release()" is a similar function but "std::move()" is better of the two
}
////////////////////
////////////////////
////////////////////
@ -509,11 +501,6 @@ std::vector<unsigned int> neroshop::Seller::get_top_rated_sellers(unsigned int l
////////////////////
////////////////////
////////////////////
// getters - wallet-related stuff
////////////////////
neroshop::Wallet * neroshop::Seller::get_wallet() const {
return wallet.get();
}
////////////////////
////////////////////
////////////////////
@ -687,19 +674,6 @@ bool neroshop::Seller::has_stock(const neroshop::Product& item) const {
return has_stock(item.get_id());
}
////////////////////
bool neroshop::Seller::has_wallet() const {
if(!wallet.get()) return false; // wallet is nullptr
if(!wallet->get_monero_wallet()) return false; // wallet not opened
return true;
}
////////////////////
bool neroshop::Seller::has_wallet_synced() const {
if(!wallet.get()) return false; // wallet is nullptr
if(!wallet->get_monero_wallet()) return false; // wallet not opened
if(!wallet->get_monero_wallet()->is_synced()) return false; // wallet not synced to daemon
return true;
}
////////////////////
////////////////////
////////////////////
// callbacks

@ -13,7 +13,6 @@
namespace neroshop {
// forward declarations
class Wallet;
class Product;
class Image;
@ -44,8 +43,6 @@ public:
void delist_item(const std::string& listing_key); // deletes an item from the inventory
// setters - item and inventory-related stuff
void set_stock_quantity(const std::string& listing_key, int quantity);
// setters - wallet-related stuff
void set_wallet(const neroshop::Wallet& wallet);// temporary - delete ASAP
// getters - seller rating system
unsigned int get_good_ratings() const; // returns the total number of good ratings given to this seller by their customers
unsigned int get_bad_ratings() const; // returns the total number of bad ratings given to this seller by their customers
@ -53,8 +50,6 @@ public:
unsigned int get_total_ratings() const; // same as get_ratings_count
unsigned int get_reputation() const; // returns a percentage of good ratings
static std::vector<unsigned int> get_top_rated_sellers(unsigned int limit = 50); // returns a container of n seller_ids with the most positive (good) ratings // the default value of n is 50
// getters - wallet-related stuff
neroshop::Wallet * get_wallet() const;
// getters - order-related stuff
unsigned int get_customer_order(unsigned int index) const;
unsigned int get_customer_order_count() const;
@ -77,8 +72,6 @@ public:
bool has_listed(const neroshop::Product& item) const; // returns true if this seller has listed an item
bool has_stock(const std::string& product_id) const; // returns true if this seller has an item in stock
bool has_stock(const neroshop::Product& item) const;
bool has_wallet() const; // returns true if seller's wallet is opened
bool has_wallet_synced() const; // returns true if seller's wallet is synced to a node
// callbacks
static neroshop::User * on_login(const neroshop::Wallet& wallet);
void on_order_received(std::string& subaddress);
@ -87,7 +80,6 @@ public:
protected:
void load_customer_orders(); // called one-time when seller logs in
private:
std::unique_ptr<neroshop::Wallet> wallet;
std::vector<int> customer_order_list;
friend class Serializer;
};

@ -15,12 +15,13 @@
#include "tools/base64.hpp"
#include "tools/timestamp.hpp"
#include "tools/string.hpp"
#include "wallet.hpp"
#include <fstream>
#include <regex>
////////////////////
neroshop::User::User() : id(""), logged(false), account_type(UserAccountType::Guest), cart(nullptr), order_list({}), favorites({}) {
neroshop::User::User() : wallet(nullptr), id(""), logged(false), account_type(UserAccountType::Guest), cart(nullptr), order_list({}), favorites({}) {
cart = std::unique_ptr<Cart>(new Cart());
}
////////////////////
@ -30,6 +31,8 @@ neroshop::User::~User()
private_key.clear();
// destroy cart
if(cart.get()) cart.reset();
// destroy wallet
if(wallet.get()) wallet.reset();
// clear orders
order_list.clear(); // this should reset (delete) all orders
// clear favorites
@ -54,7 +57,7 @@ void neroshop::User::rate_seller(const std::string& seller_id, int score, const
////if(account_type_id != 2) {neroshop::print("This user (id: " + seller_id + ") is not a seller, so they cannot be rated", 2); return;}//if(String::lower(account_type) != "seller") {neroshop::print("You cannot rate a non-seller");return;}
// Prevent seller from rating him/herself
if(seller_id == this->id) {
neroshop::print("You cannot rate yourself", 1);
std::cerr << "\033[91mYou cannot rate yourself\033[0m\n";
return; // exit function
}
/*// To prevent duplicating seller_id that is has already been rated by this user_id (a user cannot rate the same seller twice, except update his or her score rating for a specific seller_id
@ -135,8 +138,24 @@ void neroshop::User::rate_seller(const std::string& seller_id, int score, const
// Check if the rater (you) has not already rated this seller
std::string rater_id = value_obj["rater_id"].get<std::string>();
if(rater_id == this->id) {
neroshop::print("You have already rated this seller", 1);
// TODO: Update seller rating then re-sign it (key will remain the same)
std::cerr << "\033[91mYou have already rated this seller\033[0m\n";
// Self-verify the signature
std::string old_comments = value_obj["comments"].get<std::string>();
std::string old_signature = value_obj["signature"].get<std::string>();
bool self_verified = wallet->verify_message(old_comments, old_signature);
if(!self_verified) { neroshop::print("Data verification failed."); return; }
// Modify/Update the seller rating and re-signed to reflect the modification
value_obj["comments"] = comments;
value_obj["score"] = score;
assert(old_signature != signature && "Signature is outdated");
value_obj["signature"] = signature;
value_obj["last_updated"] = neroshop::timestamp::get_current_utc_timestamp(); // Should I update the timestamp or just add a last_updated field?
// Send set request containing the updated value with the same key as before
std::string modified_value = value_obj.dump();
std::string response;
client->set(key, modified_value, response); // key MUST remain unchanged!!
std::cout << "Received response (set): " << response << "\n";
std::cout << "\033[1;37;49mYour rating for seller (" + seller_id + ") has been updated (score: " << ((score != 0) ? "\033[1;32m" : "\033[1;91m") + std::to_string(score) << "\033[1;37;49m)\033[0m\n";
return;
}
}
@ -269,7 +288,7 @@ void neroshop::User::rate_item(const std::string& product_id, int stars, const s
// Check if the rater (you) has not already rated this product
std::string rater_id = value_obj["rater_id"].get<std::string>();
if(rater_id == this->id) {
neroshop::print("You have already rated this product or service", 1);
std::cerr << "\033[91mYou have already rated this product or service\033[0m\n";
// TODO: Update product rating then re-sign it (key will remain the same)
return;
}
@ -670,6 +689,10 @@ void neroshop::User::set_private_key(const std::string& private_key) {
this->private_key = private_key;
}
////////////////////
void neroshop::User::set_wallet(const neroshop::Wallet& wallet) {
std::unique_ptr<neroshop::Wallet> user_wallet(&const_cast<neroshop::Wallet&>(wallet));
this->wallet = std::move(user_wallet);
}
////////////////////
////////////////////
////////////////////
@ -736,6 +759,10 @@ std::string neroshop::User::get_private_key() const {
return private_key;
}
////////////////////
neroshop::Wallet * neroshop::User::get_wallet() const {
return wallet.get();
}
////////////////////
////////////////////
neroshop::Cart * neroshop::User::get_cart() const {
return cart.get();
@ -981,6 +1008,18 @@ bool neroshop::User::has_favorited(const std::string& listing_key_or_id) {
return false;////return (std::find(favorites.begin(), favorites.end(), product_id) != favorites.end()); // this is good for when storing favorites as integers (product_ids)
}
////////////////////
bool neroshop::User::has_wallet() const {
if(!wallet.get()) return false; // wallet is nullptr
if(!wallet->get_monero_wallet()) return false; // wallet not opened
return true;
}
////////////////////
bool neroshop::User::has_wallet_synced() const {
if(!has_wallet()) return false; // wallet is either nullptr or not opened
if(!wallet->get_monero_wallet()->is_synced()) return false; // wallet not synced to daemon
return true;
}
////////////////////
////////////////////
////////////////////
// callbacks

@ -14,6 +14,7 @@ enum class UserAccountType : unsigned int { Guest, Buyer, Seller };
namespace neroshop {
class Wallet;
class Cart; // forward declaration
class User { // base class of seller and buyer // sellers can buy and sell while buyers (including guests) can only buy but cannot sell
@ -45,8 +46,12 @@ public:
// setters
void set_public_key(const std::string& public_key);
void set_private_key(const std::string& private_key);
// setters - wallet-related stuff
void set_wallet(const neroshop::Wallet& wallet);
// getters
std::string get_public_key() const;
// getters - wallet-related stuff
neroshop::Wallet * get_wallet() const;
// account-related stuff - getters
std::string get_id() const;//unsigned int get_id() const;
std::string get_name() const;
@ -74,6 +79,8 @@ public:
// item-related stuff - boolean
bool has_purchased(const std::string& listing_key); // checks if an item was previously purchased or not
bool has_favorited(const std::string& listing_key); // checks if an item is in a user's favorites or wishlist
bool has_wallet() const; // returns true if seller's wallet is opened
bool has_wallet_synced() const; // returns true if seller's wallet is synced to a node
// callbacks
void on_registration(const std::string& name); // on registering an account
//virtual User * on_login(const std::string& username);// = 0; // load all data: orders, reputation/ratings, settings // for all users
@ -94,6 +101,7 @@ protected: // can only be accessed by classes that inherit from class User (even
void load_cart();
void load_orders(); // on login, load all orders this user has made so far (this function is called only once per login)
void load_favorites(); // on login, load favorites (this function is called only once per login)
std::unique_ptr<neroshop::Wallet> wallet;
private:
std::string id;
std::string name;

Loading…
Cancel
Save