Ejemplo n.º 1
0
    def post(self):
        # 获取用户传过来的数据
        data = request.json

        # 验证参数有效性
        # RequestParse: 验证参数类型 => 弱
        # wtforms:更灵活,参数类型、参数值... => 推荐!!
        # 构建表单 => 设置参数的要求 => data与表单绑定 => 验证数据有效性
        form = RegisterForm(data=data)
        if form.validate():

            # 注意: form.email.data
            UserProfile.create_user(
                user_profile_email=form.email.data,
                user_profile_name=form.username.data,
                password=form.password.data,
                user_profile_mobile=form.phone.data,
                user_height=form.height.data,
                user_weight=form.weight.data,
                user_age=form.age.data,
            )
            user = UserProfile.query.filter_by(
                user_profile_email=data.get("email")).first()
            result = user_schema.dump(user)
            # 返回结果
            return generate_response(data=result)
        else:
            result = form.errors
            raise FormValidateException(message=result)
Ejemplo n.º 2
0
    def post(self):
        # 获取用户传过来的数据
        data = request.json

        # 验证参数有效性
        form = UserForm(data=data)
        if form.validate():
            # # 创建用户
            # user = UserProfile(user_profile_email=data.get("email"),
            #                    user_profile_name=data.get("name"),
            #                    password=data.get("password"))
            # db.session.add(user)
            # db.session.commit()
            # result = user_schema.dump(user)
            UserProfile.create_user(user_profile_email=form.email.data,
                                    user_profile_name=form.name.data,
                                    password=form.password.data)
            user = UserProfile.query.filter_by(user_profile_email=data.get("email")).first()
            result = user_schema.dump(user)

            # 返回结果
            return generate_response(data=result)
        else:
            result = form.errors
            raise FormValidateException(message=result)
Ejemplo n.º 3
0
    def on_get(self, req, resp, id):

        max_id = req.get_param('max_ids')
        since_id = req.get_param('since_id')
        limit = req.get_param('limit') or self.MAX_ELEMENTS

        if max_id and since_id:
            follows = UserProfile.select().join(
                FollowerRelation, on=FollowerRelation.follows).where(
                    FollowerRelation.user.id == id, UserProfile.id > since_id,
                    UserProfile.id < max_id).limit(limit)
        elif max_id:
            follows = UserProfile.select().join(
                FollowerRelation, on=FollowerRelation.follows).where(
                    FollowerRelation.user.id == id,
                    UserProfile.id < max_id).limit(limit)
        elif since_id:
            follows = UserProfile.select().join(
                FollowerRelation, on=FollowerRelation.follows).where(
                    FollowerRelation.user.id == id,
                    UserProfile.id > since_id).limit(limit)
        else:
            follows = FollowerRelation.select().join(
                UserProfile, on=FollowerRelation.user).where(
                    FollowerRelation.follows.id == id).limit(limit).order_by(
                        FollowerRelation.id.desc())

        following = [follow.follows.to_json() for follow in follows]
        resp.body = json.dumps(following, default=str)
        resp.satatus = falcon.HTTP_200
Ejemplo n.º 4
0
def populate_db():
    for i in range(15):
        target = UserProfile.create(
            username=f'test{i}',
            password=passw,
            name=f'test#{i}',
            email=f'fort{i}@gma.com',
            confirmation_sent_at=datetime.datetime.now(),
            last_sign_in_at=1)

        print(f"Created user {target.username}")

        target.follow(yab)

        print("Following user")
        #crate some followers
        for j in range(i):
            if j != i:
                user = UserProfile.get(username=f'test{j}')
                print(f'{user.username} -> {target.username}')
                user.follow(target, True)

        #craete some images via API
        print("Uploading some pics")
        for j in range(PHOTOS):
            print(f'Image {j} of {PHOTOS}')
            """
Ejemplo n.º 5
0
 async def on_turn(self, context: TurnContext,
                   logic: Callable[[TurnContext], Awaitable]):
     context_user_id = context.activity.from_property.id
     if context_user_id.isdigit():
         await context.send_activity(f'Valid UserId: {context_user_id}')
         user_profile = UserProfile()
         user_profile.user_id = context_user_id
         context.turn_state['user_profile'] = user_profile
         await logic()
Ejemplo n.º 6
0
    def test_create_profile_missing_fields(self):
        user = self.register_user()
        payload = {
            "photoFsRef": "https://google.com",
            "coverPhotoFsRef": "https://google.com",
            "tagline": "Some Tagline",
            "user_id": user.id
        }

        profile = UserProfile(**payload)
        profile.save()

        self.assertEqual(1, profile.id)
Ejemplo n.º 7
0
    def on_post(self, req, resp):

        if req.get_param('media_ids'):
            user = req.context['user']

            status = Status(
                caption=req.get_param('status') or '',
                visibility=bool(req.get_param('visibility')), #False if None
                user=user,
                sensitive=bool(req.get_param('sensitive')),
                remote=False,
                story=bool(req.get_param('is_story'))
            )

            if status.sensitive:
                status.spoliet_text=req.get_param('spoiler_text')

            status.save()

            if  req.get_param('media_ids') != None:
                    for image in req.get_param('media_ids').split(','):
                        m = Media.get_or_none(media_name=image)
                        m.status = status
                        m.save()

            #Increment the number of posts uploaded
            UserProfile.update({UserProfile.statuses_count: UserProfile.statuses_count + 1}).where(UserProfile.id == user.id).execute()
            spread_status(status)
            resp.status = falcon.HTTP_200
            resp.body = json.dumps(status.to_json(),default=str)

        elif req.get_param('in_reply_to_id'):

            replying_to = Status.get_or_none(id=req.get_param('in_reply_to_id'))
            if replying_to:
                status = Status(
                    caption = req.get_param('status'),
                    user = user,
                    remote = False,
                    story = False,
                    in_reply_to = replying_to,
                    sensitive = replying_to.sensitive,
                    spoiler_text = req.get_param('spoiler_text') or replying_to.spoiler_text
                )
            else:
                resp.status = falcon.HTTP_500
                resp.body = json.dumps({"Error": "Replying to bad ID"})
        else:
            resp.status = falcon.HTTP_500
            resp.body = json.dumps({"Error": "No photo attached"})
Ejemplo n.º 8
0
    def test_create_profile(self):
        user = self.register_user()
        payload = {
            "photoFsRef": "https://google.com",
            "coverPhotoFsRef": "https://google.com",
            "tagline": "Some Tagline",
            "short_bio": "Short Bio",
            "country": "PH",
            "user_id": user.id
        }

        profile = UserProfile(**payload)
        profile.save()

        self.assertEqual(1, profile.id)
Ejemplo n.º 9
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.")
Ejemplo n.º 10
0
    def on_get(self, req, resp):

        resp.append_header("Content-Type","application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#")

        response = {
            "version": "2.0",
            "software": {
                "name": "Anfora",
                "version": "Anfora {}".format(VERSION),
            },
            "protocols": ["activitypub"],
            "services": {"inbound": [], "outbound": []},
            "openRegistrations": False,
            "usage": {
                "users": {
                    "total": UserProfile.select().count()
                },
                "localPosts": Status.select().count()
            },
            "metadata": {
                "sourceCode": "https://github.com/anforaProject/anfora",
                "nodeName": NODENAME,
            },
        }

        resp.body = json.dumps(response)
        resp.status = falcon.HTTP_200
Ejemplo n.º 11
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()
Ejemplo n.º 12
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
Ejemplo n.º 13
0
def populate_for_travis():
    for i in range(15):
        target = UserProfile.create(
            username=f'test{i}',
            password=passw,
            name=f'test#{i}',
            email=f'fort{i}@gma.com',
            confirmation_sent_at=datetime.datetime.now(),
            last_sign_in_at=1)
        target.follow(yab)

        #crate some followers
        for j in range(i):
            if j != i:
                user = UserProfile.get(username=f'test{j}')
                user.follow(target, True)
Ejemplo n.º 14
0
    async def get(self):

        number_of_users = await self.application.objects.count(
            UserProfile.select())
        number_of_statuses = await self.application.objects.count(
            Status.select())

        response = {
            "version": "2.0",
            "software": {
                "name": "Anfora",
                "version": "Anfora {}".format(VERSION),
            },
            "protocols": ["activitypub"],
            "services": {
                "inbound": [],
                "outbound": []
            },
            "openRegistrations": False,
            "usage": {
                "users": {
                    "total": number_of_users
                },
                "localPosts": number_of_statuses
            },
            "metadata": {
                "sourceCode": "https://github.com/anforaProject/anfora",
                "nodeName": NODENAME,
            },
        }

        self.write(response)
Ejemplo n.º 15
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
Ejemplo n.º 16
0
    def post(self):
        # 获取参数
        parser = RequestParser()
        parser.add_argument('mobile',
                            type=type_mobile,
                            required=True,
                            location='json')
        parser.add_argument('code',
                            type=regex(r'^\d{6}$'),
                            required=True,
                            location='json')
        args = parser.parse_args()
        mobile = args.mobile
        code = args.code

        # 校验短信验证码
        key = "app:code:{}".format(mobile)
        try:
            real_code = current_app.redis_master.get(key)
        except BaseException as e:
            current_app.logger.error(e)  # 记录日志
            real_code = current_app.redis_slave.get(
                key)  # 如果主数据库连接失败, 再到数据库中获取

        # 一旦取出, 验证码就要删除 (验证码只能使用一次)
        # try:
        #     current_app.redis_master.delete(key)
        # except BaseException as e:
        #     current_app.logger.error(e)

        if not real_code or real_code.decode() != code:
            return {'message': "Invalid code", "data": None}, 400

        # 到数据库中查询该用户
        user = User.query.filter_by(mobile=mobile).first()

        if not user:  # 如果没有, 生成一条新的用户数据
            # 生成分布式id
            user_id = current_app.id_worker.get_id()
            # 添加user记录
            user = User(id=user_id,
                        mobile=mobile,
                        name=mobile,
                        last_login=datetime.now())
            db.session.add(user)
            # 添加user_profile记录
            user_profile = UserProfile(id=user_id)
            db.session.add(user_profile)
        else:
            user.last_login = datetime.now()
            user_id = user.id

        db.session.commit()

        # 记录用户状态, 生成jwt
        access_token, refresh_token = self._generate_tokens(user_id)

        # 返回json数据
        return {'access_token': access_token, "refresh_token": refresh_token}
Ejemplo n.º 17
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
Ejemplo n.º 18
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
Ejemplo n.º 19
0
def remove_status(status):
    r = redis.StrictRedis(host=os.environ.get('REDIS_HOST', 'localhost'))

    # Remove it from the own timeline
    TimelineManager(status.user).remove_from_home(status)
    # Remove it from the followers timeline
    for follower in status.user.followers():
        TimelineManager(follower).remove_from_home(status)

    #Update the user posts count

    UserProfile.update({
        UserProfile.statuses_count:
        UserProfile.statuses_count - 1
    }).where(UserProfile.id == status.user.id).execute()

    # Remove the status
    status.delete_instance(recursive=True)
Ejemplo n.º 20
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
Ejemplo n.º 21
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
Ejemplo n.º 22
0
    async def get(self):

        query = await self.application.objects.execute(
            UserProfile.select().limit(5))

        data = [n.to_json() for n in query]

        self.write(json.dumps(data, default=str))
        self.set_status(200)
Ejemplo n.º 23
0
def new_user(username, password, email,
             is_remote = False, confirmed=False, is_private = False, 
             is_admin=False, public_key=None, name=None, description = "", ap_id = None, public_inbox=None):

    """
        Returns False or UserProfile
    """
    
    # Verify username

    logging.debug(f"Starting to create user {username}")

    if not valid_username(username):
        logging.error(f"@{username} is a not valid username")
        return False

    # Hash the password
    passw = bcrypt.hashpw(password, salt_code)

    # First we create the actual user

    user = User.create(
        username = username,
        password = passw,
        email = email, 
        confirmed = confirmed,
        is_admin = is_admin,
        is_private = is_private,
    )

    logging.debug(f"Created user {user.username}")

    if name == None:
        name = username

    # Now we create the profile
    try:
        profile = UserProfile.create(
            id = user.id,
            disabled = True,
            is_remote = is_remote,
            user = user,
            name = name,
            public_key = public_key,
            ap_id = ap_id,
            description = description,
            public_inbox = public_inbox

        )
        
        logging.info(f"New Profile created: {profile}")
        return profile
    except Exception as e:
        logging.error(e)
        user.delete_instance()
        return False
Ejemplo n.º 24
0
    def post(self):
        """
        登录创建token
        """
        json_parser = RequestParser()
        json_parser.add_argument('mobile',
                                 type=parser.mobile,
                                 required=True,
                                 location='json')
        json_parser.add_argument('code',
                                 type=parser.regex(r'^\d{6}$'),
                                 required=True,
                                 location='json')
        args = json_parser.parse_args()
        mobile = args.mobile
        code = args.code

        # 从redis中获取验证码
        key = 'app:code:{}'.format(mobile)
        try:
            real_code = current_app.redis_master.get(key)
        except ConnectionError as e:
            current_app.logger.error(e)
            real_code = current_app.redis_slave.get(key)

        try:
            current_app.redis_master.delete(key)
        except ConnectionError as e:
            current_app.logger.error(e)

        if not real_code or real_code.decode() != code:
            return {'message': 'Invalid code.'}, 400

        # 查询或保存用户
        user = User.query.filter_by(mobile=mobile).first()

        if user is None:
            # 用户不存在,注册用户
            # 雪花算法生成一个分布式ID
            user_id = current_app.id_worker.get_id()

            user = User(id=user_id,
                        mobile=mobile,
                        name=mobile,
                        last_login=datetime.now())
            db.session.add(user)
            profile = UserProfile(id=user.id)
            db.session.add(profile)
            db.session.commit()
        else:
            if user.status == User.STATUS.DISABLE:
                return {'message': 'Invalid user.'}, 403

        token, refresh_token = self._generate_tokens(user.id)

        return {'token': token, 'refresh_token': refresh_token}, 201
Ejemplo n.º 25
0
    async def get(self, username: str):

        try:
            user = await self.application.objects.get(
                UserProfile.select().join(User).where(
                    User.username == username.lower()))

            self.redirect(f'/accounts/{user.id}')
        except:
            self.redirect('/404')
Ejemplo n.º 26
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
Ejemplo n.º 27
0
def new_user(username,
             password,
             email,
             is_remote=False,
             confirmed=False,
             is_private=False,
             is_admin=False,
             public_key=None,
             name=None,
             description="",
             ap_id=None):
    """
        Returns False or UserProfile
    """

    # Verify username

    if not valid_username(username):
        return False

    # Hash the password

    passw = bcrypt.hashpw(password.encode('utf-8'), salt_code.encode('utf-8'))

    # First we create the actual user

    user = User.create(username=username,
                       password=passw,
                       email=email,
                       confirmed=confirmed,
                       is_admin=is_admin,
                       is_private=is_private)

    if name == None:
        name = username

    # Now we create the profile

    profile = UserProfile.create(id=user.id,
                                 disabled=True,
                                 is_remote=is_remote,
                                 user=user,
                                 name=name,
                                 public_key=public_key,
                                 ap_id=ap_id,
                                 description=description)

    # Send the confirmation email

    if not user.confirmed:
        send_activation_email(profile)

    return profile
Ejemplo n.º 28
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
Ejemplo n.º 29
0
    def create(self,
               user,
               caption,
               sensitive,
               public,
               spoiler=None,
               remote=False,
               story=False,
               media_ids):
        """
            user: UserProfile - User creating the status
            caption: str - Image caption
            sensitive: bool - Content has something sensitive.
            spoiler: str - Content spoiler text
            public: bool - True if yes
            media_ids: list - A list with the media related to the status

            Returns the created status

        """

        status = Status.create(caption=caption,
                               is_public=public,
                               user=user,
                               sensitive=sensitive,
                               spoiler_text=spoiler,
                               remote=remote,
                               is_story=story)

        for image in req.get_param('media_ids').split(','):
            m = Media.get_or_none(media_name=image)
            m.status = status
            m.save()

        UserProfile.update({
            UserProfile.statuses_count:
            UserProfile.statuses_count + 1
        }).where(UserProfile.id == status.user.id).execute()
        spread_status(status)
Ejemplo n.º 30
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