class MarketProtocol(RPCProtocol): implements(MessageProcessor) def __init__(self, node_proto, router): self.router = router RPCProtocol.__init__(self, node_proto, router) self.log = Logger(system=self) self.handled_commands = [GET_CONTRACT, GET_IMAGE] self.multiplexer = None self.hashmap = HashMap() def connect_multiplexer(self, multiplexer): self.multiplexer = multiplexer def rpc_get_contract(self, sender, contract_hash): self.log.info("Looking up contract ID %s" % contract_hash.encode('hex')) self.router.addContact(sender) try: with open(self.hashmap.get_file(contract_hash), "r") as file: contract = file.read() return [contract] except: return ["None"] def rpc_get_image(self, sender, image_hash): self.log.info("Looking up image with hash %s" % image_hash.encode('hex')) self.router.addContact(sender) try: with open(self.hashmap.get_file(image_hash), "r") as file: image = file.read() return [image] except: return ["None"] def callGetContract(self, nodeToAsk, contract_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_contract(address, contract_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetImage(self, nodeToAsk, image_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_image(address, image_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def handleCallResponse(self, result, node): """ If we get a response, add the node to the routing table. If we get no response, make sure it's removed from the routing table. """ if result[0]: self.log.info("got response from %s, adding to router" % node) self.router.addContact(node) else: self.log.debug("no response from %s, removing from router" % node) self.router.removeContact(node) return result def __iter__(self): return iter(self.handled_commands)
def setimage(): parser = argparse.ArgumentParser( description="Maps a image hash to a file path in the database", usage='''usage: networkcli.py setimage [-f FILEPATH]''') parser.add_argument('-f', '--filepath', help="a path to the image") args = parser.parse_args(sys.argv[2:]) with open(args.filepath, "r") as f: image = f.read() d = digest(image) h = HashMap() h.insert(d, args.filepath) print h.get_file(d)
def delete(self, delete_images=True): """ Deletes the contract json from the OpenBazaar directory as well as the listing metadata from the db and all the related images in the file system. """ # build the file_name from the contract file_name = str(self.contract["vendor_offer"]["listing"]["item"]["title"][:100]) file_name = re.sub(r"[^\w\s]", '', file_name) file_name = re.sub(r"\s+", '_', file_name) file_path = DATA_FOLDER + "store/listings/contracts/" + file_name + ".json" h = HashMap() # maybe delete the images from disk if "image_hashes" in self.contract["vendor_offer"]["listing"]["item"] and delete_images: for image_hash in self.contract["vendor_offer"]["listing"]["item"]["image_hashes"]: # delete from disk image_path = h.get_file(unhexlify(image_hash)) if os.path.exists(image_path): os.remove(image_path) # remove pointer to the image from the HashMap h.delete(unhexlify(image_hash)) # delete the contract from disk if os.path.exists(file_path): os.remove(file_path) # delete the listing metadata from the db contract_hash = digest(json.dumps(self.contract, indent=4)) ListingsStore().delete_listing(contract_hash) # remove the pointer to the contract from the HashMap h.delete(contract_hash)
def delete(self, delete_images=True): """ Deletes the contract json from the OpenBazaar directory as well as the listing metadata from the db and all the related images in the file system. """ # build the file_name from the contract file_name = str( self.contract["vendor_offer"]["listing"]["item"]["title"][:100]) file_name = re.sub(r"[^\w\s]", '', file_name) file_name = re.sub(r"\s+", '_', file_name) file_path = DATA_FOLDER + "store/listings/contracts/" + file_name + ".json" h = HashMap() # maybe delete the images from disk if "image_hashes" in self.contract["vendor_offer"]["listing"][ "item"] and delete_images: for image_hash in self.contract["vendor_offer"]["listing"]["item"][ "image_hashes"]: # delete from disk image_path = h.get_file(unhexlify(image_hash)) if os.path.exists(image_path): os.remove(image_path) # remove pointer to the image from the HashMap h.delete(unhexlify(image_hash)) # delete the contract from disk if os.path.exists(file_path): os.remove(file_path) # delete the listing metadata from the db contract_hash = digest(json.dumps(self.contract, indent=4)) ListingsStore().delete_listing(contract_hash) # remove the pointer to the contract from the HashMap h.delete(contract_hash)
def update(self, expiration_date=None, metadata_category=None, title=None, description=None, currency_code=None, price=None, process_time=None, nsfw=None, est_delivery_domestic=None, est_delivery_international=None, shipping_origin=None, shipping_regions=None, keywords=None, category=None, condition=None, sku=None, image_hashes=None, # if intending to delete an image, pass in # the hashes that are staying. images=None, # to add new images pass in a list of image files. free_shipping=None, shipping_currency_code=None, shipping_domestic=None, shipping_international=None): self.delete(False) vendor_listing = self.contract["vendor_offer"]["listing"] if expiration_date is not None: vendor_listing["item"]["expiry"] = expiration_date if metadata_category is not None: vendor_listing["metadata"]["category"] = metadata_category if metadata_category != "physical good" and vendor_listing["metadata"][ "category"] == "physical good": del vendor_listing["shipping"] elif metadata_category == "physical good" and vendor_listing["metadata"][ "category"] != "physical good": vendor_listing["shipping"] = {} vendor_listing["shipping"]["est_delivery"] = {} vendor_listing["shipping"]["free"] = False if title is not None: vendor_listing["item"]["title"] = title if description is not None: vendor_listing["item"]["description"] = description if currency_code is not None: if currency_code.upper() != "BTC" and "bitcoin" \ in vendor_listing["item"]["price_per_unit"]: p = vendor_listing["item"]["price_per_unit"]["bitcoin"] del vendor_listing["item"]["price_per_unit"]["bitcoin"] vendor_listing["item"]["price_per_unit"]["fiat"] = {} vendor_listing["item"]["price_per_unit"]["fiat"][ "currency_code"] = currency_code vendor_listing["item"]["price_per_unit"]["fiat"]["price"] = p elif currency_code.upper() == "BTC" and "fiat" in \ vendor_listing["item"]["price_per_unit"]: p = vendor_listing["item"]["price_per_unit"]["fiat"]["price"] del vendor_listing["item"]["price_per_unit"]["fiat"] vendor_listing["item"]["price_per_unit"]["bitcoin"] = p if price is not None: if "bitcoin" in vendor_listing["item"]["price_per_unit"]: vendor_listing["item"]["price_per_unit"]["bitcoin"] = price else: vendor_listing["item"]["price_per_unit"]["fiat"]["price"] = price if process_time is not None: vendor_listing["item"]["process_time"] = process_time if nsfw is not None: vendor_listing["item"]["nsfw"] = nsfw if keywords is not None: vendor_listing["item"]["keywords"] = [] vendor_listing["item"]["keywords"].extend(keywords) if category is not None: vendor_listing["item"]["category"] = category if image_hashes is not None: to_delete = list(set(vendor_listing["item"]["image_hashes"]) - set(image_hashes)) for image_hash in to_delete: # delete from disk h = HashMap() image_path = h.get_file(unhexlify(image_hash)) if os.path.exists(image_path): os.remove(image_path) # remove pointer to the image from the HashMap h.delete(unhexlify(image_hash)) vendor_listing["item"]["image_hashes"] = [] vendor_listing["item"]["image_hashes"].extend(image_hashes) if images is not None: if "image_hashes" not in vendor_listing["item"]: vendor_listing["item"]["image_hashes"] = [] for image in images: hash_value = digest(image).encode("hex") vendor_listing["item"]["image_hashes"].append(hash_value) with open(DATA_FOLDER + "store/media/" + hash_value, 'w') as outfile: outfile.write(image) HashMap().insert(digest(image), DATA_FOLDER + "store/media/" + hash_value) if vendor_listing["metadata"]["category"] == "physical good" and condition is not None: vendor_listing["item"]["condition"] = condition if sku is not None: vendor_listing["item"]["sku"] = sku if vendor_listing["metadata"]["category"] == "physical good": if shipping_origin is not None: vendor_listing["shipping"]["shipping_origin"] = shipping_origin if free_shipping is not None: if free_shipping is True and vendor_listing["shipping"]["free"] is False: vendor_listing["shipping"]["free"] = True del vendor_listing["shipping"]["flat_fee"] elif free_shipping is False and vendor_listing["shipping"]["free"] is True: vendor_listing["shipping"]["flat_fee"] = {} vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {} vendor_listing["shipping"]["free"] = False if shipping_currency_code is not None and vendor_listing["shipping"]["free"] is False: if shipping_currency_code == "BTC" and "bitcoin" not in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {} d = vendor_listing["shipping"]["flat_fee"]["fiat"]["price"]["domestic"] i = vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "international"] vendor_listing["shipping"]["flat_fee"]["bitcoin"]["domestic"] = d vendor_listing["shipping"]["flat_fee"]["bitcoin"]["international"] = i del vendor_listing["shipping"]["flat_fee"]["fiat"] elif shipping_currency_code != "BTC" and "bitcoin" in \ vendor_listing["shipping"]["flat_fee"]: d = vendor_listing["shipping"]["flat_fee"]["bitcoin"]["domestic"] i = vendor_listing["shipping"]["flat_fee"]["bitcoin"]["international"] vendor_listing["shipping"]["flat_fee"]["fiat"] = {} vendor_listing["shipping"]["flat_fee"]["fiat"]["price"] = {} vendor_listing["shipping"]["flat_fee"]["fiat"]["price"]["domestic"] = d vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "international"] = i vendor_listing["shipping"]["flat_fee"]["fiat"][ "currency_code"] = shipping_currency_code del vendor_listing["shipping"]["flat_fee"]["bitcoin"] if shipping_domestic is not None and "bitcoin" not in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "domestic"] = shipping_domestic if shipping_international is not None and "bitcoin" not in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "international"] = shipping_international if shipping_domestic is not None and "bitcoin" in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "domestic"] = shipping_domestic if shipping_international is not None and "bitcoin" in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "international"] = shipping_international if shipping_regions is not None: vendor_listing["shipping"]["shipping_regions"] = shipping_regions if est_delivery_domestic is not None: vendor_listing["shipping"]["est_delivery"]["domestic"] = est_delivery_domestic if est_delivery_international is not None: vendor_listing["shipping"]["est_delivery"][ "international"] = est_delivery_international self.save()
class MarketProtocol(RPCProtocol): implements(MessageProcessor) def __init__(self, node_proto, router, signing_key): self.router = router RPCProtocol.__init__(self, node_proto, router) self.log = Logger(system=self) self.multiplexer = None self.hashmap = HashMap() self.signing_key = signing_key self.listeners = [] self.handled_commands = [GET_CONTRACT, GET_IMAGE, GET_PROFILE, GET_LISTINGS, GET_USER_METADATA, GET_CONTRACT_METADATA, FOLLOW, UNFOLLOW, GET_FOLLOWERS, GET_FOLLOWING, NOTIFY, MESSAGE] def connect_multiplexer(self, multiplexer): self.multiplexer = multiplexer def add_listener(self, listener): self.listeners.append(listener) def rpc_get_contract(self, sender, contract_hash): self.log.info("Looking up contract ID %s" % contract_hash.encode('hex')) self.router.addContact(sender) try: with open(self.hashmap.get_file(contract_hash), "r") as filename: contract = filename.read() return [contract] except Exception: self.log.warning("Could not find contract %s" % contract_hash.encode('hex')) return ["None"] def rpc_get_image(self, sender, image_hash): self.log.info("Looking up image with hash %s" % image_hash.encode('hex')) self.router.addContact(sender) try: with open(self.hashmap.get_file(image_hash), "r") as filename: image = filename.read() return [image] except Exception: self.log.warning("Could not find image %s" % image_hash.encode('hex')) return ["None"] def rpc_get_profile(self, sender): self.log.info("Fetching profile") self.router.addContact(sender) try: proto = Profile().get(True) return [proto, self.signing_key.sign(proto)[:64]] except Exception: self.log.error("Unable to load the profile") return ["None"] def rpc_get_user_metadata(self, sender): self.log.info("Fetching metadata") self.router.addContact(sender) try: proto = Profile().get(False) m = Metadata() m.name = proto.name m.handle = proto.handle m.short_description = proto.short_description m.avatar_hash = proto.avatar_hash m.nsfw = proto.nsfw return [m.SerializeToString(), self.signing_key.sign(m.SerializeToString())[:64]] except Exception: self.log.error("Unable to get the profile metadata") return ["None"] def rpc_get_listings(self, sender): self.log.info("Fetching listings") self.router.addContact(sender) try: p = Profile().get() l = Listings() l.ParseFromString(ListingsStore().get_proto()) l.handle = p.handle l.avatar_hash = p.avatar_hash return [l.SerializeToString(), self.signing_key.sign(l.SerializeToString())[:64]] except Exception: self.log.warning("Could not find any listings in the database") return ["None"] def rpc_get_contract_metadata(self, sender, contract_hash): self.log.info("Fetching metadata for contract %s" % hexlify(contract_hash)) self.router.addContact(sender) try: proto = ListingsStore().get_proto() l = Listings() l.ParseFromString(proto) for listing in l.listing: if listing.contract_hash == contract_hash: ser = listing.SerializeToString() return [ser, self.signing_key.sign(ser)[:64]] except Exception: self.log.warning("Could not find metadata for contract %s" % hexlify(contract_hash)) return ["None"] def rpc_follow(self, sender, proto, signature): self.log.info("Follow request from %s" % sender.id.encode("hex")) self.router.addContact(sender) try: verify_key = nacl.signing.VerifyKey(sender.signed_pubkey[64:]) verify_key.verify(proto, signature) f = Followers.Follower() f.ParseFromString(proto) if f.guid != sender.id: raise Exception('GUID does not match sending node') if f.following != self.proto.guid: raise Exception('Following wrong node') f.signature = signature FollowData().set_follower(f) proto = Profile().get(False) m = Metadata() m.name = proto.name m.handle = proto.handle m.avatar_hash = proto.avatar_hash m.nsfw = proto.nsfw return ["True", m.SerializeToString(), self.signing_key.sign(m.SerializeToString())[:64]] except Exception: self.log.warning("Failed to validate follower") return ["False"] def rpc_unfollow(self, sender, signature): self.log.info("Unfollow request from %s" % sender.id.encode("hex")) self.router.addContact(sender) try: verify_key = nacl.signing.VerifyKey(sender.signed_pubkey[64:]) verify_key.verify("unfollow:" + self.proto.guid, signature) f = FollowData() f.delete_follower(sender.id) return ["True"] except Exception: self.log.warning("Failed to validate follower signature") return ["False"] def rpc_get_followers(self, sender): self.log.info("Fetching followers list from db") self.router.addContact(sender) ser = FollowData().get_followers() if ser is None: return ["None"] else: return [ser, self.signing_key.sign(ser)[:64]] def rpc_get_following(self, sender): self.log.info("Fetching following list from db") self.router.addContact(sender) ser = FollowData().get_following() if ser is None: return ["None"] else: return [ser, self.signing_key.sign(ser)[:64]] def rpc_notify(self, sender, message, signature): if len(message) <= 140 and FollowData().is_following(sender.id): try: verify_key = nacl.signing.VerifyKey(sender.signed_pubkey[64:]) verify_key.verify(message, signature) except Exception: return ["False"] self.log.info("Received a notification from %s" % sender) self.router.addContact(sender) for listener in self.listeners: try: verifyObject(NotificationListener, listener) listener.notify(sender.id, message) except DoesNotImplement: pass return ["True"] else: return ["False"] def rpc_message(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) plaintext = box.decrypt(encrypted) p = Plaintext_Message() p.ParseFromString(plaintext) signature = p.signature p.ClearField("signature") verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:]) verify_key.verify(p.SerializeToString(), signature) h = nacl.hash.sha512(p.signed_pubkey) pow_hash = h[64:128] if int(pow_hash[:6], 16) >= 50 or hexlify(p.sender_guid) != h[:40] or p.sender_guid != sender.id: raise Exception('Invalid guid') self.log.info("Received a message from %s" % sender) self.router.addContact(sender) for listener in self.listeners: try: verifyObject(MessageListener, listener) listener.notify(p, signature) except DoesNotImplement: pass return ["True"] except Exception: self.log.error("Received invalid message from %s" % sender) return ["False"] def callGetContract(self, nodeToAsk, contract_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_contract(address, contract_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetImage(self, nodeToAsk, image_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_image(address, image_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetProfile(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_profile(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetUserMetadata(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_user_metadata(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetListings(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_listings(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetContractMetadata(self, nodeToAsk, contract_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_contract_metadata(address, contract_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callFollow(self, nodeToAsk, proto, signature): address = (nodeToAsk.ip, nodeToAsk.port) d = self.follow(address, proto, signature) return d.addCallback(self.handleCallResponse, nodeToAsk) def callUnfollow(self, nodeToAsk, signature): address = (nodeToAsk.ip, nodeToAsk.port) d = self.unfollow(address, signature) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetFollowers(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_followers(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetFollowing(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_following(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callNotify(self, nodeToAsk, message, signature): address = (nodeToAsk.ip, nodeToAsk.port) d = self.notify(address, message, signature) return d.addCallback(self.handleCallResponse, nodeToAsk) def callMessage(self, nodeToAsk, ehemeral_pubkey, ciphertext): address = (nodeToAsk.ip, nodeToAsk.port) d = self.message(address, ehemeral_pubkey, ciphertext) return d.addCallback(self.handleCallResponse, nodeToAsk) def handleCallResponse(self, result, node): """ If we get a response, add the node to the routing table. If we get no response, make sure it's removed from the routing table. """ if result[0]: self.log.info("got response from %s, adding to router" % node) self.router.addContact(node) else: self.log.debug("no response from %s, removing from router" % node) self.router.removeContact(node) return result def __iter__(self): return iter(self.handled_commands)
class MarketProtocol(RPCProtocol): implements(MessageProcessor) def __init__(self, node_proto, router, signing_key): self.router = router RPCProtocol.__init__(self, node_proto, router) self.log = Logger(system=self) self.multiplexer = None self.hashmap = HashMap() self.signing_key = signing_key self.listeners = [] self.handled_commands = [ GET_CONTRACT, GET_IMAGE, GET_PROFILE, GET_LISTINGS, GET_USER_METADATA, GET_CONTRACT_METADATA, FOLLOW, UNFOLLOW, GET_FOLLOWERS, GET_FOLLOWING, NOTIFY, MESSAGE ] def connect_multiplexer(self, multiplexer): self.multiplexer = multiplexer def add_listener(self, listener): self.listeners.append(listener) def rpc_get_contract(self, sender, contract_hash): self.log.info("Looking up contract ID %s" % contract_hash.encode('hex')) self.router.addContact(sender) try: with open(self.hashmap.get_file(contract_hash), "r") as filename: contract = filename.read() return [contract] except Exception: self.log.warning("Could not find contract %s" % contract_hash.encode('hex')) return ["None"] def rpc_get_image(self, sender, image_hash): self.log.info("Looking up image with hash %s" % image_hash.encode('hex')) self.router.addContact(sender) try: with open(self.hashmap.get_file(image_hash), "r") as filename: image = filename.read() return [image] except Exception: self.log.warning("Could not find image %s" % image_hash.encode('hex')) return ["None"] def rpc_get_profile(self, sender): self.log.info("Fetching profile") self.router.addContact(sender) try: proto = Profile().get(True) return [proto, self.signing_key.sign(proto)[:64]] except Exception: self.log.error("Unable to load the profile") return ["None"] def rpc_get_user_metadata(self, sender): self.log.info("Fetching metadata") self.router.addContact(sender) try: proto = Profile().get(False) m = Metadata() m.name = proto.name m.handle = proto.handle m.avatar_hash = proto.avatar_hash m.nsfw = proto.nsfw return [ m.SerializeToString(), self.signing_key.sign(m.SerializeToString())[:64] ] except Exception: self.log.error("Unable to get the profile metadata") return ["None"] def rpc_get_listings(self, sender): self.log.info("Fetching listings") self.router.addContact(sender) try: proto = ListingsStore().get_proto() return [proto, self.signing_key.sign(proto)[:64]] except Exception: self.log.warning("Could not find any listings in the database") return ["None"] def rpc_get_contract_metadata(self, sender, contract_hash): self.log.info("Fetching metadata for contract %s" % hexlify(contract_hash)) self.router.addContact(sender) try: proto = ListingsStore().get_proto() l = Listings() l.ParseFromString(proto) for listing in l.listing: if listing.contract_hash == contract_hash: country_code = Profile().get().country_code listing.country_code = country_code ser = listing.SerializeToString() return [ser, self.signing_key.sign(ser)[:64]] except Exception: self.log.warning("Could not find metadata for contract %s" % hexlify(contract_hash)) return ["None"] def rpc_follow(self, sender, proto, signature): self.log.info("Follow request from %s" % sender.id.encode("hex")) self.router.addContact(sender) try: verify_key = nacl.signing.VerifyKey(sender.signed_pubkey[64:]) verify_key.verify(proto, signature) f = Followers.Follower() f.ParseFromString(proto) if f.guid != sender.id: raise Exception('GUID does not match sending node') if f.following != self.proto.guid: raise Exception('Following wrong node') f.signature = signature FollowData().set_follower(f) proto = Profile().get(False) m = Metadata() m.name = proto.name m.handle = proto.handle m.avatar_hash = proto.avatar_hash m.nsfw = proto.nsfw return [ "True", m.SerializeToString(), self.signing_key.sign(m.SerializeToString())[:64] ] except Exception: self.log.warning("Failed to validate follower") return ["False"] def rpc_unfollow(self, sender, signature): self.log.info("Unfollow request from %s" % sender.id.encode("hex")) self.router.addContact(sender) try: verify_key = nacl.signing.VerifyKey(sender.signed_pubkey[64:]) verify_key.verify("unfollow:" + self.proto.guid, signature) f = FollowData() f.delete_follower(sender.id) return ["True"] except Exception: self.log.warning("Failed to validate follower signature") return ["False"] def rpc_get_followers(self, sender): self.log.info("Fetching followers list from db") self.router.addContact(sender) ser = FollowData().get_followers() if ser is None: return ["None"] else: return [ser, self.signing_key.sign(ser)[:64]] def rpc_get_following(self, sender): self.log.info("Fetching following list from db") self.router.addContact(sender) ser = FollowData().get_following() if ser is None: return ["None"] else: return [ser, self.signing_key.sign(ser)[:64]] def rpc_notify(self, sender, message, signature): if len(message) <= 140 and FollowData().is_following(sender.id): try: verify_key = nacl.signing.VerifyKey(sender.signed_pubkey[64:]) verify_key.verify(message, signature) except Exception: return ["False"] self.log.info("Received a notification from %s" % sender) self.router.addContact(sender) for listener in self.listeners: try: verifyObject(NotificationListener, listener) listener.notify(sender.id, message) except DoesNotImplement: pass return ["True"] else: return ["False"] def rpc_message(self, sender, pubkey, encrypted): try: box = Box( PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) plaintext = box.decrypt(encrypted) p = Plaintext_Message() p.ParseFromString(plaintext) signature = p.signature p.ClearField("signature") verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:]) verify_key.verify(p.SerializeToString(), signature) h = nacl.hash.sha512(p.signed_pubkey) pow_hash = h[64:128] if int(pow_hash[:6], 16) >= 50 or hexlify( p.sender_guid) != h[:40] or p.sender_guid != sender.id: raise Exception('Invalid guid') self.log.info("Received a message from %s" % sender) self.router.addContact(sender) for listener in self.listeners: try: verifyObject(MessageListener, listener) listener.notify(p, signature) except DoesNotImplement: pass return ["True"] except Exception: self.log.error("Received invalid message from %s" % sender) return ["False"] def callGetContract(self, nodeToAsk, contract_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_contract(address, contract_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetImage(self, nodeToAsk, image_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_image(address, image_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetProfile(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_profile(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetUserMetadata(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_user_metadata(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetListings(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_listings(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetContractMetadata(self, nodeToAsk, contract_hash): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_contract_metadata(address, contract_hash) return d.addCallback(self.handleCallResponse, nodeToAsk) def callFollow(self, nodeToAsk, proto, signature): address = (nodeToAsk.ip, nodeToAsk.port) d = self.follow(address, proto, signature) return d.addCallback(self.handleCallResponse, nodeToAsk) def callUnfollow(self, nodeToAsk, signature): address = (nodeToAsk.ip, nodeToAsk.port) d = self.unfollow(address, signature) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetFollowers(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_followers(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callGetFollowing(self, nodeToAsk): address = (nodeToAsk.ip, nodeToAsk.port) d = self.get_following(address) return d.addCallback(self.handleCallResponse, nodeToAsk) def callNotify(self, nodeToAsk, message, signature): address = (nodeToAsk.ip, nodeToAsk.port) d = self.notify(address, message, signature) return d.addCallback(self.handleCallResponse, nodeToAsk) def callMessage(self, nodeToAsk, ehemeral_pubkey, ciphertext): address = (nodeToAsk.ip, nodeToAsk.port) d = self.message(address, ehemeral_pubkey, ciphertext) return d.addCallback(self.handleCallResponse, nodeToAsk) def handleCallResponse(self, result, node): """ If we get a response, add the node to the routing table. If we get no response, make sure it's removed from the routing table. """ if result[0]: self.log.info("got response from %s, adding to router" % node) self.router.addContact(node) else: self.log.debug("no response from %s, removing from router" % node) self.router.removeContact(node) return result def __iter__(self): return iter(self.handled_commands)
def update( self, expiration_date=None, metadata_category=None, title=None, description=None, currency_code=None, price=None, process_time=None, nsfw=None, est_delivery_domestic=None, est_delivery_international=None, shipping_origin=None, shipping_regions=None, keywords=None, category=None, condition=None, sku=None, image_hashes=None, # if intending to delete an image, pass in # the hashes that are staying. images=None, # to add new images pass in a list of image files. free_shipping=None, shipping_currency_code=None, shipping_domestic=None, shipping_international=None): self.delete(False) vendor_listing = self.contract["vendor_offer"]["listing"] if expiration_date is not None: vendor_listing["item"]["expiry"] = expiration_date if metadata_category is not None: vendor_listing["metadata"]["category"] = metadata_category if metadata_category != "physical good" and vendor_listing["metadata"][ "category"] == "physical good": del vendor_listing["shipping"] elif metadata_category == "physical good" and vendor_listing[ "metadata"]["category"] != "physical good": vendor_listing["shipping"] = {} vendor_listing["shipping"]["est_delivery"] = {} vendor_listing["shipping"]["free"] = False if title is not None: vendor_listing["item"]["title"] = title if description is not None: vendor_listing["item"]["description"] = description if currency_code is not None: if currency_code.upper() != "BTC" and "bitcoin" \ in vendor_listing["item"]["price_per_unit"]: p = vendor_listing["item"]["price_per_unit"]["bitcoin"] del vendor_listing["item"]["price_per_unit"]["bitcoin"] vendor_listing["item"]["price_per_unit"]["fiat"] = {} vendor_listing["item"]["price_per_unit"]["fiat"][ "currency_code"] = currency_code vendor_listing["item"]["price_per_unit"]["fiat"]["price"] = p elif currency_code.upper() == "BTC" and "fiat" in \ vendor_listing["item"]["price_per_unit"]: p = vendor_listing["item"]["price_per_unit"]["fiat"]["price"] del vendor_listing["item"]["price_per_unit"]["fiat"] vendor_listing["item"]["price_per_unit"]["bitcoin"] = p if price is not None: if "bitcoin" in vendor_listing["item"]["price_per_unit"]: vendor_listing["item"]["price_per_unit"]["bitcoin"] = price else: vendor_listing["item"]["price_per_unit"]["fiat"][ "price"] = price if process_time is not None: vendor_listing["item"]["process_time"] = process_time if nsfw is not None: vendor_listing["item"]["nsfw"] = nsfw if keywords is not None: vendor_listing["item"]["keywords"] = [] vendor_listing["item"]["keywords"].extend(keywords) if category is not None: vendor_listing["item"]["category"] = category if image_hashes is not None: to_delete = list( set(vendor_listing["item"]["image_hashes"]) - set(image_hashes)) for image_hash in to_delete: # delete from disk h = HashMap() image_path = h.get_file(unhexlify(image_hash)) if os.path.exists(image_path): os.remove(image_path) # remove pointer to the image from the HashMap h.delete(unhexlify(image_hash)) vendor_listing["item"]["image_hashes"] = [] vendor_listing["item"]["image_hashes"].extend(image_hashes) if images is not None: if "image_hashes" not in vendor_listing["item"]: vendor_listing["item"]["image_hashes"] = [] for image in images: hash_value = digest(image).encode("hex") vendor_listing["item"]["image_hashes"].append(hash_value) with open(DATA_FOLDER + "store/media/" + hash_value, 'w') as outfile: outfile.write(image) HashMap().insert(digest(image), DATA_FOLDER + "store/media/" + hash_value) if vendor_listing["metadata"][ "category"] == "physical good" and condition is not None: vendor_listing["item"]["condition"] = condition if sku is not None: vendor_listing["item"]["sku"] = sku if vendor_listing["metadata"]["category"] == "physical good": if shipping_origin is not None: vendor_listing["shipping"]["shipping_origin"] = shipping_origin if free_shipping is not None: if free_shipping is True and vendor_listing["shipping"][ "free"] is False: vendor_listing["shipping"]["free"] = True del vendor_listing["shipping"]["flat_fee"] elif free_shipping is False and vendor_listing["shipping"][ "free"] is True: vendor_listing["shipping"]["flat_fee"] = {} vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {} vendor_listing["shipping"]["free"] = False if shipping_currency_code is not None and vendor_listing[ "shipping"]["free"] is False: if shipping_currency_code == "BTC" and "bitcoin" not in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {} d = vendor_listing["shipping"]["flat_fee"]["fiat"][ "price"]["domestic"] i = vendor_listing["shipping"]["flat_fee"]["fiat"][ "price"]["international"] vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "domestic"] = d vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "international"] = i del vendor_listing["shipping"]["flat_fee"]["fiat"] elif shipping_currency_code != "BTC" and "bitcoin" in \ vendor_listing["shipping"]["flat_fee"]: d = vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "domestic"] i = vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "international"] vendor_listing["shipping"]["flat_fee"]["fiat"] = {} vendor_listing["shipping"]["flat_fee"]["fiat"][ "price"] = {} vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "domestic"] = d vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "international"] = i vendor_listing["shipping"]["flat_fee"]["fiat"][ "currency_code"] = shipping_currency_code del vendor_listing["shipping"]["flat_fee"]["bitcoin"] if shipping_domestic is not None and "bitcoin" not in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "domestic"] = shipping_domestic if shipping_international is not None and "bitcoin" not in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][ "international"] = shipping_international if shipping_domestic is not None and "bitcoin" in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "domestic"] = shipping_domestic if shipping_international is not None and "bitcoin" in \ vendor_listing["shipping"]["flat_fee"]: vendor_listing["shipping"]["flat_fee"]["bitcoin"][ "international"] = shipping_international if shipping_regions is not None: vendor_listing["shipping"][ "shipping_regions"] = shipping_regions if est_delivery_domestic is not None: vendor_listing["shipping"]["est_delivery"][ "domestic"] = est_delivery_domestic if est_delivery_international is not None: vendor_listing["shipping"]["est_delivery"][ "international"] = est_delivery_international self.save()