Esempio n. 1
0
    def on_get(self, req, resp):

        # For now I will assume that webfinger only asks for the actor, so resources
        # is just one element.
        if not 'resource' in req.params.keys():
            raise falcon.HTTPBadRequest(description="No resource was provided along the request.")
        
        resources = req.params['resource']


        username, domain = extract_user(resources)

        if username == None and domain == None:
            raise falcon.HTTPBadRequest(description="Unable to decode resource.")

        if domain == DOMAIN:
            user = UserProfile.get_or_none(username=username)

            if user:
                response = Webfinger(user).generate()
                resp.body = json.dumps(response)
                resp.status = falcon.HTTP_200
            else:
                raise falcon.HTTPNotFound(description="User was not found.")
        else:
            raise falcon.HTTPBadRequest(description="Resouce domain doesn't match local domain.")
Esempio n. 2
0
    def uri_to_resource(self, klass):

        if self._local_uri(self.uri):
            if klass.__name__ == 'User':
                return UserProfile.get_or_none(ap_id=self.uri)
        else:
            return self.get_or_create_remote_user()
Esempio n. 3
0
 def get_or_create_remote_user(self):
     """ 
         Returns an instance of User after looking for it using it's ap_id
     """
     logging.debug(self.uri)
     user = UserProfile.get_or_none(ap_id=self.uri)
     if user == None:
         user = self.dereference()
         hostname = urlparse(user.id).hostname
         #username = "******".format(user.preferredUsername, hostname)
         logging.debug(
             f"I'm going to request the creation of user with username @{user.preferredUsername}"
         )
         user = new_user(username=user.preferredUsername,
                         name=user.name,
                         ap_id=user.id,
                         is_remote=True,
                         email=None,
                         password="******",
                         description=user.summary,
                         is_private=user.manuallyApprovesFollowers,
                         public_key=user.publicKey['publicKeyPem'])
     #print(user)
     logging.debug(f"remote user: {user}")
     return user
Esempio n. 4
0
 def on_get(self, req, resp, id):
     person = UserProfile.get_or_none(id=id)
     if person:
         resp.body = json.dumps(person.to_json(), default=json_serial)
         resp.status = falcon.HTTP_200
     else:
         resp.status = falcon.HTTP_404
Esempio n. 5
0
def loadUserPass(username, password):
    candidate = UserProfile.get_or_none(username=username)

    if candidate != None:
        if Argon2().check_password_hash(candidate.password, password):
            return candidate
        else:
            return None
Esempio n. 6
0
 def on_get(self, req, resp, id):
     user = UserProfile.get_or_none(id=id)
     if user:
         followers = [follower.to_json() for follower in user.followers()]
         resp.body = json.dumps(followers, default=str)
         resp.status = falcon.HTTP_200
     else:
         resp.status = falcon.HTTP_404
Esempio n. 7
0
 def on_get(self, req, resp, username):
     user = UserProfile.get_or_none(username=username)
     if user:
         followers = [follower.uris.id for follower in user.followers()]
         resp.body = json.dumps(
             activities.OrderedCollection(followers).to_json(), default=str)
         resp.status = falcon.HTTP_200
     else:
         resp.status = falcon.HTTP_404
Esempio n. 8
0
    def on_get(self, req, resp, username):
        user = UserProfile.get_or_none(username == username)
        objects = user.photos.select().order_by(Status.created_at.desc())

        collectionPage = activities.OrderedCollectionPage(
            map(activities.Note, objects))
        collection = activities.OrderedCollection([collectionPage])
        resp.body = json.dumps(collection.to_json(context=True))
        resp.status = falcon.HTTP_200
Esempio n. 9
0
async def handle_follow(activity):

    # Find if the target user is in our system
    followed = UserProfile.get_or_none(ap_id=activity.object)
    
    if followed:
        logging.debug(f"Starting follow process for {followed.username}")
        # Get the ap_id for the actor
        ap_id = ""
        if isinstance(activity.actor, activities.Actor):
            ap_id = activity.actor.id
        elif isinstance(activity.actor, str):
            ap_id = activity.actor

        # A representation of the remote user
        follower = ActivityPubId(ap_id).get_or_create_remote_user()
        logging.debug(f"New follower: {follower}")
        # Handle if the user must manually approve request 
        if followed.is_private:
            FollowRequest.create(
                account = follower,
                target = followed
            )
        else:

            # Handle local things
            #follower.follow(followed)
            #NotificationManager(follower).create_follow_notification(followed)

            message = {
                "@context": "https://www.w3.org/ns/activitystreams",
                "type": "Accept",
                "to": follower.uris.inbox,
                "actor": followed.ap_id,

                # this is wrong per litepub, but mastodon < 2.4 is not compliant with that profile.
                "object": {
                    "type": "Follow",
                    "id": followed.ap_id,
                    "object": "https://{}/actor".format('pleroma.test'),
                    "actor": follower.ap_id
                },

                "id": "https://{}/activities/{}".format('anfora.test', uuid.uuid4()),
            }


            await push_to_remote_actor(follower, message , f'{BASE_URL}/actor#main-key')
            return True
    else:
        logging.error(f"User not found: {activity.object}")
        return False
Esempio n. 10
0
    def on_get(self, req, resp, id):

        user = UserProfile.get_or_none(id=id)
        if user:
            statuses = [
                x.to_json()
                for x in user.statuses.order_by(Status.created_at.desc())
            ]
            resp.body = json.dumps(statuses, default=str)
            resp.status = falcon.HTTP_200

        else:
            resp.body = json.dumps({"Error: No such user"})
            resp.status = falcon.HTTP_404
Esempio n. 11
0
    def on_get(self, req, resp, id):
        user = UserProfile.get_or_none(id=id)
        if user:
            if 'max_id' in req.params.keys():
                feed = generate_feed(user, req.params['max_id'])
            else:
                feed = generate_feed(user)

            resp.status = falcon.HTTP_200
            resp.body = feed
            resp.content_type = falcon.MEDIA_XML
        else:

            resp.status = falcon.HTTP_404
Esempio n. 12
0
    def on_post(self, req, resp, username):
        user = UserProfile.get_or_none(username == username)

        if req.context['user'].username != username:
            resp.status = falcon.HTTP_401
            resp.body = json.dumps({"Error": "Access denied"})

        payload = req.get_param('data')
        activity = json.loads(payload, object_hook=as_activitystream)

        if activity.object.type == "Note":
            obj = activity.object
            activity = activities.Create(to=user.uris.followers,
                                         actor=user.uris.id,
                                         object=obj)

        activity.validate()

        if activity.type == "Create":
            if activity.object.type != "Note":
                resp.status = falcon.HTTP_500
                resp.body = json.dumps({"Error": "You only can create notes"})

                activity.object.id = photo.uris.id
                activity.id = store(activity, user)
                #deliver(activity)
                resp.body = json.dumps({"Success": "Delivered successfully"})
                resp.status = falcon.HTTP_200

                #Convert to jpeg

            else:
                resp.status = falcon.HTTP_500
                resp.body = json.dumps({"Error": "No photo attached"})

        if activity.type == "Follow":

            followed = ActivityPubId(
                activity.object).get_or_create_remote_user()
            user = req.context["user"]
            #print(followed.ap_id, user.username, followed.username)
            f = FollowerRelation.create(user=user, follows=followed)

            activity.actor = user.uris.id
            activity.to = followed.uris.id
            #activity.id = store(activity, user)
            deliver(activity)

            resp.body = json.dumps({"Success": "Delivered successfully"})
            resp.status = falcon.HTTP_200
Esempio n. 13
0
def handle_follow(activity):
    followed = UserProfile.get_or_none(ap_id=activity.object)
    print("=> Handling follow")
    if followed:
        if isinstance(activity.actor, activities.Actor):
            ap_id = activity.actor.id
        elif isinstance(activity.actor, str):
            ap_id = activity.actor

        follower = ActivityPubId(ap_id).get_or_create_remote_user()
        FollowerRelation.create(user=follower, follows=followed)

        response = {"Type": "Accept", "Object": activity}

    else:
        print("error handling follow")
Esempio n. 14
0
def handle_follow(activity):
    followed = UserProfile.get_or_none(ap_id=activity.object)
    print(activity.object)
    if followed:
        ap_id = ""
        if isinstance(activity.actor, activities.Actor):
            ap_id = activity.actor.id
        elif isinstance(activity.actor, str):
            ap_id = activity.actor

        follower = ActivityPubId(ap_id).get_or_create_remote_user()

        if followed.is_private:
            FollowRequest.create(account=follower, target=followed)
        else:
            follower.follow(followed, valid=True)
            t = Accept(object=activity, actor=followed.ap_id)
            data = LinkedDataSignature(t.to_json())
            signed = data.sign(followed)

            headers = {
                'date': f'{datetime.datetime.utcnow():%d-%b-%YT%H:%M:%SZ}',
                "(request-target)": follower.uris.inbox,
                "content-type": "application/activity+json",
                "host": DOMAIN,
            }

            signature = SignatureVerification(headers,
                                              method="POST",
                                              path=activity.actor +
                                              '/inbox').sign(followed)

            headers.update({'signature': signature})

            logger.debug('Records: %s', headers)

            r = requests.post(follower.ap_id, data=signed, headers=headers)
            print(r.status_code)
            logger.debug('Records: %s', r.status_code + "\n" + r.json())
            print("sent ", signed, signature)
            return True
    else:
        return False
Esempio n. 15
0
 def get_or_create_remote_user(self):
     """ 
         Returns an instance of User after looking for it using it's ap_id
     """
     user = UserProfile.get_or_none(ap_id=self.uri)
     if not user:
         user = self.dereference()
         hostname = urlparse(user.id).hostname
         username = "******".format(user.preferredUsername, hostname)
         user = UserProfile.create(
             username=user.preferredUsername,
             name=user.name,
             ap_id=user.id,
             remote=True,
             password="******",
             description=user.summary,
             private=user.manuallyApprovesFollowers,
             public_key=user.publicKey['publicKeyPem'])
     #print(user)
     return user
Esempio n. 16
0
def handle_follow(activity, original=None):
    # Find if the target user is in our system
    followed = UserProfile.get_or_none(ap_id=activity.object)

    if followed:
        logging.debug(f"Starting follow process for {followed.username}")
        # Get the ap_id for the actor
        ap_id = ""
        if isinstance(activity.actor, activities.Actor):
            ap_id = activity.actor.id
        elif isinstance(activity.actor, str):
            ap_id = activity.actor

        # A representation of the remote user
        follower = ActivityPubId(ap_id).get_or_create_remote_user()
        logging.debug(f"New follower: {follower}")
        # Handle if the user must manually approve request
        if followed.is_private:
            FollowRequest.create(account=follower, target=followed)
        else:

            # Handle local things
            follower.follow(followed)
            NotificationManager(follower).create_follow_notification(followed)
            message = {
                "@context": "https://www.w3.org/ns/activitystreams",
                "type": "Accept",
                "to": follower.ap_id,
                "actor": followed.ap_id,
                "object": original,
                "id": followed.ap_id + '#accepts/follows/' + str(uuid.uuid4()),
            }

            response = push_to_remote_actor(follower, message)

            return response
    else:
        logging.error(f"User not found: {activity.object}")
        return False
Esempio n. 17
0
def loadUser(payload):
    candidate = UserProfile.get_or_none(username=payload['user']['username'])
    return candidate
Esempio n. 18
0
 def user_from_uri(uri):
     username, domain = extract_user(uri)
     user = UserProfile.get_or_none(username=username)
     return user