示例#1
0
 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"]
示例#2
0
 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"]
示例#3
0
 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"]
示例#4
0
    def send_notification(self, message):
        """
        Sends a notification message to all online followers. It will resolve
        each guid before sending the notification. Messages must be less than
        140 characters. Returns the number of followers the notification reached.
        """

        if len(message) > 140:
            return defer.succeed(0)

        def send(nodes):
            def how_many_reached(responses):
                count = 0
                for resp in responses:
                    if resp[1][0] and resp[1][1][0] == "True":
                        count += 1
                return count

            ds = []
            signature = self.signing_key.sign(str(message))[:64]
            for n in nodes:
                if n[1] is not None:
                    ds.append(self.protocol.callNotify(n[1], message, signature))
            return defer.DeferredList(ds).addCallback(how_many_reached)
        dl = []
        f = objects.Followers()
        f.ParseFromString(FollowData().get_followers())
        for follower in f.followers:
            dl.append(self.kserver.resolve(follower.guid))
        return defer.DeferredList(dl).addCallback(send)
示例#5
0
 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]]
示例#6
0
 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"]
示例#7
0
 def save_to_db(result):
     if result[0] and result[1][0] == "True":
         try:
             u = objects.Following.User()
             u.guid = node_to_follow.id
             u.signed_pubkey = node_to_follow.signed_pubkey
             m = objects.Metadata()
             m.ParseFromString(result[1][1])
             u.metadata.MergeFrom(m)
             u.signature = result[1][2]
             pubkey = node_to_follow.signed_pubkey[64:]
             verify_key = nacl.signing.VerifyKey(pubkey)
             verify_key.verify(result[1][1], result[1][2])
             FollowData().follow(u)
             return True
         except Exception:
             return False
     else:
         return False
    def get_following(self, request):
        def parse_following(following):
            if following is not None:
                response = {"following": []}
                for f in following.users:
                    user_json = {
                        "guid": f.guid.encode("hex"),
                        "handle": f.metadata.handle,
                        "name": f.metadata.name,
                        "avatar_hash": f.metadata.avatar_hash.encode("hex"),
                        "nsfw": f.metadata.nsfw
                    }
                    response["following"].append(user_json)
                request.setHeader('content-type', "application/json")
                request.write(json.dumps(response, indent=4))
                request.finish()
            else:
                request.write(NoResource().render(request))
                request.finish()

        if "guid" in request.args:

            def get_node(node):
                if node is not None:
                    self.mserver.get_following(node).addCallback(
                        parse_following)
                else:
                    request.write(NoResource().render(request))
                    request.finish()

            self.kserver.resolve(unhexlify(
                request.args["guid"][0])).addCallback(get_node)
        else:
            ser = FollowData().get_following()
            if ser is not None:
                f = objects.Following()
                f.ParseFromString(ser)
                parse_following(f)
            else:
                parse_following(None)
        return server.NOT_DONE_YET
 def notify(self, guid, message):
     # pull the metadata for this node from the db
     f = Following()
     ser = FollowData().get_following()
     if ser is not None:
         f.ParseFromString(ser)
         for user in f.users:
             if user.guid == guid:
                 avatar_hash = user.metadata.avatar_hash
                 handle = user.metadata.handle
     timestamp = int(time.time())
     NotificationStore().save_notification(guid, handle, message, timestamp, avatar_hash)
     notification_json = {
         "notification": {
             "guid": guid.encode("hex"),
             "message": message,
             "timestamp": timestamp,
             "avatar_hash": avatar_hash.encode("hex")
         }
     }
     if handle:
         notification_json["notification"]["handle"] = handle
     self.ws.push(json.dumps(notification_json, indent=4))
示例#10
0
 def save_to_db(result):
     if result[0] and result[1][0] == "True":
         FollowData().unfollow(node_to_unfollow.id)
         return True
     else:
         return False