예제 #1
0
    def receive_message(self, datagram, connection):
        m = Message()
        try:
            m.ParseFromString(datagram)
            sender = node.Node(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey, m.sender.vendor)
        except Exception:
            # If message isn't formatted property then ignore
            self.log.warning("Received unknown message from %s, ignoring" % str(connection.dest_addr))
            return False

        # Check that the GUID is valid. If not, ignore
        if self.router.isNewNode(sender):
            try:
                pubkey = m.sender.signedPublicKey[len(m.sender.signedPublicKey) - 32:]
                verify_key = nacl.signing.VerifyKey(pubkey)
                verify_key.verify(m.sender.signedPublicKey)
                h = nacl.hash.sha512(m.sender.signedPublicKey)
                pow_hash = h[64:128]
                if int(pow_hash[:6], 16) >= 50 or hexlify(m.sender.guid) != h[:40]:
                    raise Exception('Invalid GUID')

            except Exception:
                self.log.warning("Received message from sender with invalid GUID, ignoring")
                return False

        if m.sender.vendor:
            VendorStore().save_vendor(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey)

        msgID = m.messageID
        data = tuple(m.arguments)
        if msgID in self._outstanding:
            self._acceptResponse(msgID, data, sender)
        else:
            self._acceptRequest(msgID, str(Command.Name(m.command)).lower(), data, sender, connection)
예제 #2
0
 def handle_response(listings, node):
     count = 0
     if listings is not None:
         for l in listings.listing:
             if l.contract_hash not in self.factory.outstanding[
                     message_id]:
                 listing_json = {
                     "id": message_id,
                     "listing": {
                         "guid": node.id.encode("hex"),
                         "handle": listings.handle,
                         "avatar_hash":
                         listings.avatar_hash.encode("hex"),
                         "title": l.title,
                         "contract_hash": l.contract_hash.encode("hex"),
                         "thumbnail_hash":
                         l.thumbnail_hash.encode("hex"),
                         "category": l.category,
                         "price": l.price,
                         "currency_code": l.currency_code,
                         "nsfw": l.nsfw,
                         "origin": str(CountryCode.Name(l.origin)),
                         "ships_to": []
                     }
                 }
                 for country in l.ships_to:
                     listing_json["listing"]["ships_to"].append(
                         str(CountryCode.Name(country)))
                 if not os.path.isfile(DATA_FOLDER + 'cache/' +
                                       l.thumbnail_hash.encode("hex")):
                     self.factory.mserver.get_image(
                         node, l.thumbnail_hash)
                 if not os.path.isfile(
                         DATA_FOLDER + 'cache/' +
                         listings.avatar_hash.encode("hex")):
                     self.factory.mserver.get_image(
                         node, listings.avatar_hash)
                 self.sendMessage(json.dumps(listing_json, indent=4),
                                  False)
                 count += 1
                 self.factory.outstanding[message_id].append(
                     l.contract_hash)
                 if count == 3:
                     return count
         vendors.remove(node)
     else:
         VendorStore().delete_vendor(node.id)
         vendors.remove(node)
     return count
예제 #3
0
    def get_vendors(self, message_id):
        if message_id in self.factory.outstanding:
            vendors = self.factory.outstanding[message_id]
        else:
            vendors = VendorStore().get_vendors()
            shuffle(vendors)
            self.factory.outstanding[message_id] = vendors

        def count_results(results):
            to_query = 0
            for result in results:
                if not result:
                    to_query += 1
            for node in vendors[:to_query]:
                dl.append(
                    self.factory.mserver.get_user_metadata(node).addCallback(
                        handle_response, node))
                defer.gatherResults(dl).addCallback(count_results)

        def handle_response(metadata, node):
            if metadata is not None:
                vendor = {
                    "id": message_id,
                    "vendor": {
                        "guid": node.id.encode("hex"),
                        "name": metadata.name,
                        "handle": metadata.handle,
                        "avatar_hash": metadata.avatar_hash.encode("hex"),
                        "nsfw": metadata.nsfw
                    }
                }
                self.sendMessage(json.dumps(vendor, indent=4), False)
                vendors.remove(node)
                return True
            else:
                VendorStore().delete_vendor(node.id)
                vendors.remove(node)
                return False

        dl = []
        for node in vendors[:30]:
            dl.append(
                self.factory.mserver.get_user_metadata(node).addCallback(
                    handle_response, node))
        defer.gatherResults(dl).addCallback(count_results)
예제 #4
0
 def handle_response(metadata, node):
     if metadata is not None:
         vendor = {
             "id": message_id,
             "vendor": {
                 "guid": node.id.encode("hex"),
                 "name": metadata.name,
                 "handle": metadata.handle,
                 "avatar_hash": metadata.avatar_hash.encode("hex"),
                 "nsfw": metadata.nsfw
             }
         }
         self.sendMessage(json.dumps(vendor, indent=4), False)
         vendors.remove(node)
         return True
     else:
         VendorStore().delete_vendor(node.id)
         vendors.remove(node)
         return False
예제 #5
0
    def get_homepage_listings(self, message_id):
        if message_id not in self.factory.outstanding:
            self.factory.outstanding[message_id] = []
        vendors = VendorStore().get_vendors()
        shuffle(vendors)

        def count_results(results):
            to_query = 30
            for result in results:
                to_query -= result
            shuffle(vendors)
            if to_query / 3 > 0 and len(vendors) > 0:
                for node in vendors[:to_query / 3]:
                    dl.append(
                        self.factory.mserver.get_listings(node).addCallback(
                            handle_response, node))
                defer.gatherResults(dl).addCallback(count_results)

        def handle_response(listings, node):
            count = 0
            if listings is not None:
                for l in listings.listing:
                    if l.contract_hash not in self.factory.outstanding[
                            message_id]:
                        listing_json = {
                            "id": message_id,
                            "listing": {
                                "guid": node.id.encode("hex"),
                                "handle": listings.handle,
                                "avatar_hash":
                                listings.avatar_hash.encode("hex"),
                                "title": l.title,
                                "contract_hash": l.contract_hash.encode("hex"),
                                "thumbnail_hash":
                                l.thumbnail_hash.encode("hex"),
                                "category": l.category,
                                "price": l.price,
                                "currency_code": l.currency_code,
                                "nsfw": l.nsfw,
                                "origin": str(CountryCode.Name(l.origin)),
                                "ships_to": []
                            }
                        }
                        for country in l.ships_to:
                            listing_json["listing"]["ships_to"].append(
                                str(CountryCode.Name(country)))
                        if not os.path.isfile(DATA_FOLDER + 'cache/' +
                                              l.thumbnail_hash.encode("hex")):
                            self.factory.mserver.get_image(
                                node, l.thumbnail_hash)
                        if not os.path.isfile(
                                DATA_FOLDER + 'cache/' +
                                listings.avatar_hash.encode("hex")):
                            self.factory.mserver.get_image(
                                node, listings.avatar_hash)
                        self.sendMessage(json.dumps(listing_json, indent=4),
                                         False)
                        count += 1
                        self.factory.outstanding[message_id].append(
                            l.contract_hash)
                        if count == 3:
                            return count
                vendors.remove(node)
            else:
                VendorStore().delete_vendor(node.id)
                vendors.remove(node)
            return count

        dl = []
        for vendor in vendors[:10]:
            dl.append(
                self.factory.mserver.get_listings(vendor).addCallback(
                    handle_response, vendor))
        defer.gatherResults(dl).addCallback(count_results)