示例#1
0
    def login_user(data):
        # Assign variables
        email = data["email"]
        password = data["password"]

        try:
            # Check if email or password was provided
            if not email or not password:
                resp = Message(False, "Credentials not fully provided")
                resp["error_reason"] = "no_credentials"
                return resp, 403

            # Fetch the user data
            user = User.query.filter_by(email=email).first()
            if not user:
                resp = Message(
                    False,
                    "The email you have entered does not match any account")
                resp["error_reason"] = "email_404"
                return resp, 404

            elif user and user.check_password(password):
                user_schema = UserSchema()
                user_info = user_schema.dump(user)

                # Remove sensitive information
                for info in private_info:
                    del user_info[info]

                # Check if the user has an avatar
                if user_info["profile_picture"]:
                    user_info["avatar"] = get_image(
                        user_info["profile_picture"], "avatars")

                access_token = create_access_token(identity=user.id)

                if access_token:
                    resp = Message(True, "Successfully logged in.")
                    resp["access_token"] = access_token
                    resp["user"] = user_info
                    return resp, 200

            # Return incorrect password if others fail
            resp = Message(False,
                           "Failed to log in, password may be incorrect")
            resp["error_reason"] = "invalid_password"
            return resp, 403

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#2
0
    def get(post_public_id, current_user):
        # Get the specific post using its public id
        post = Post.query.filter_by(public_id=post_public_id).first()

        if not post:
            resp = Message(False, "Post not found!")
            resp["error_reason"] = "data_404"
            return resp, 404

        post_info = load_post(post, current_user.id)

        resp = Message(True, "Post info sent.")
        resp["post"] = post_info
        return resp, 200
示例#3
0
def send_notification(data, target_user_public_id):

    actor = load_user(get_jwt_identity())
    action = data["action"]

    # Post, Comment, Reply, etc.
    object_type = data["object_type"]
    object_public_id = data["object_public_id"]

    # Get the target user
    target_user = User.query.filter_by(public_id=target_user_public_id).first()

    if action not in valid_actions:
        resp = Message(False, "Invalid action!")
        resp["error_reason"] = "action_invalid"
        return resp, 403

    # Validate
    if object_type not in allowed_types:
        resp = Message(False, "Object type is invalid!")
        resp["error_reason"] = "object_invalid"
        return resp, 403

    notification = Notification.query.filter_by(
        object_type=object_type, object_public_id=object_public_id
    ).first()

    if notification is not None:
        return None, 204

    try:
        new_notification = Notification(
            target_owner=target_user.id,
            actor=actor.public_id,
            action=action,
            timestamp=datetime.utcnow(),
            object_type=object_type,
            object_public_id=object_public_id,
        )

        db.session.add(new_notification)
        db.session.commit()

        resp = Message(True, "Notification has been created.")
        return resp, 201

    except Exception as error:
        current_app.logger.error(error)
        return InternalErrResp()
示例#4
0
    def create(comment_public_id, data, current_user):
        # Get the comment
        comment = Comment.query.filter_by(public_id=comment_public_id).first()

        if not comment:
            resp = Message(False, "Comment not found!")
            resp["error_reason"] = "comment_404"
            return resp, 404

        # Assign the vars
        content = data["content"]
        limit = 1500

        if not content:
            resp = Message(False, "Reply content not found!")
            return resp, 404

        elif len(content) > limit:
            resp = Message(False, f"Reply content exceeds limits ({ limit })")
            return resp, 403

        try:
            # Create new reply obj.
            new_reply = Reply(
                public_id=str(uuid4().int)[:15],
                owner_id=current_user.id,
                creator_public_id=current_user.public_id,
                on_comment=comment.id,
                content=content,
            )

            latest_reply = add_reply_and_flush(new_reply, current_user.id)

            # Notify commenter
            notify(
                "replied",
                "reply",
                latest_reply["public_id"],
                latest_reply["creator_public_id"],
            )

            resp = Message(True, "Replied on comment.")
            resp["reply"] = latest_reply
            return resp, 201

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#5
0
    def get_replies_data(id_array, current_user):
        # Check if the array is empty
        if len(id_array) == 0 or id_array is None:
            ## Nothing to send back...
            return "", 204

        replies = []

        replies_query = Reply.query.filter(Reply.id.in_(id_array)).all()

        try:
            for reply in replies_query:
                reply_info = load_reply(reply, current_user.id)
                replies.append(reply_info)

            # Re-sort it back to the original array
            res = [
                reply for id in id_array for reply in replies
                if reply["id"] == id
            ]

            resp = Message(True, "Comments info sent.")
            resp["replies"] = res
            return resp, 200

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#6
0
    def get_notifs_info(id_array, current_user):
        # Check if the array is empty
        if len(id_array) == 0 or id_array is None:
            return None, 204

        notifs = []

        notif_query = Notification.query.filter(
            Notification.id.in_(id_array)).all()

        try:
            for notification in notif_query:
                notif_info = notification_schema.dump(notification)

                # Load the actor as user
                actor = load_user(notif_info["actor"])
                actor_info = user_schema.dump(actor)
                notif_info["actor_info"] = filter_author(actor_info)

                notifs.append(notif_info)

            # Re-sort it back to the original array
            res = [
                notif for id in id_array for notif in notifs
                if notif["id"] == id
            ]

            resp = Message(True, "Notifications sent.")
            resp["notifications"] = res
            return resp, 200

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#7
0
    def comment(comment_public_id, current_user):
        # Query for the comment
        comment = Comment.query.filter_by(public_id=comment_public_id).first()

        # Check if the comment exists
        if not comment:
            return "", 404

        # Check if the user already liked
        if check_like(comment.likes, current_user.id):
            return "", 403

        # Create a new like obj.
        comment_like = CommentLike(on_comment=comment.id,
                                   owner_id=current_user.id,
                                   liked_on=datetime.utcnow())

        try:
            # Notify comment owner
            if current_user.public_id != comment.creator_public_id:
                notify("liked", "comment", comment.public_id,
                       comment.creator_public_id)

            add_like(comment_like)

            resp = Message(True, "User has liked the comment.")
            return resp, 201

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#8
0
    def get_comments_data(id_array, current_user):
        # Check if the array is empty
        if len(id_array) == 0 or id_array is None:
            ## Nothing to send back...
            return "", 204

        comments = []

        comments_query = Comment.query.filter(Comment.id.in_(id_array)).all()

        try:
            for comment in comments_query:
                comment_info = load_comment(comment, current_user.id)
                comments.append(comment_info)

            # Re-sort it back to the original array
            res = [
                comment for id in id_array for comment in comments
                if comment["id"] == id
            ]

            resp = Message(True, "Comments info sent.")
            resp["comments"] = res
            return resp, 200

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#9
0
    def get_activity(query_limit):
        # Get Posts IDs by latest activity (latest comment on post)

        # Get Posts info
        # Currently set limits
        posts = Post.query.with_entities(
            Post.id, Post.created).limit(query_limit).all()

        post_info = load_info_many(posts)

        # Comments
        # Limit into 10 latest active posts
        comments = Comment.query.limit(10).all()

        comment_info = comments_schema.dump(comments)

        # Get the activity based on the latest comments
        post_activity_from_comments = [{
            "id": c["post"],
            "created": c["created"]
        } for c in comment_info]

        feed = uniq(x["id"] for x in sorted(
            post_activity_from_comments + post_info,
            key=lambda x: x["created"],
            reverse=True,
        ))

        resp = Message(True, "Post IDs sent.")
        resp["post_ids"] = feed
        return resp, 200
示例#10
0
    def get_posts_data(id_array, current_user):

        # Check if the array is empty
        if len(id_array) == 0 or id_array is None:
            ## Nothing to send back..
            return "", 204

        posts = []

        posts_query = Post.query.filter(Post.id.in_(id_array)).all()

        try:
            for post in posts_query:
                post_info = load_post(post, current_user.id)
                posts.append(post_info)

            # Re-sort it back to the original array
            res = [
                post for id in id_array for post in posts if post["id"] == id
            ]

            resp = Message(True, "Posts info sent.")
            resp["posts"] = res
            return resp, 200

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#11
0
    def delete(comment_public_id, current_user):
        # Query for the comment
        comment = Comment.query.filter_by(public_id=comment_public_id).first()

        if not comment:
            resp = Message(False, "Comment not found!")
            return resp, 204

        # Check comment owner
        elif current_user.public_id == comment.creator_public_id:
            try:
                delete_comment(comment)

                resp = Message(True, "Comment has been deleted.")
                return resp, 200

            except Exception as error:
                current_app.logger.error(error)
                return InternalErrResp()

        resp = Message(False, "Insufficient permissions!")
        return resp, 403
示例#12
0
    def delete(post_public_id, current_user):
        post = Post.query.filter_by(public_id=post_public_id).first()

        if not post:
            resp = Message(False, "Post not found!")
            resp["error_reason"] = "post_404"
            return resp, 404

        # Check post owner
        elif (current_user.public_id == post.creator_public_id
              ):  # or is_admin(current_user)
            try:
                delete_post(post)

                resp = Message(True, "Post has been deleted.")
                return resp, 200

            except Exception as error:
                current_app.logger.error(error)
                return InternalErrResp()

        resp = Message(False, "Insufficient permissions!")
        return resp, 403
示例#13
0
    def update(reply_public_id, data, current_user):
        reply = Reply.query.filter_by(public_id=reply_public_id).first()

        if not reply:
            resp = Message(False, "Reply not found!")
            resp["error_reason"] = "reply_404"
            return resp, 404

        # Check reply owner
        elif current_user.public_id == reply.creator_public_id:
            try:
                update_reply(reply, data["content"])

                resp = Message(True, "Reply updated.")
                return resp, 200

            except Exception as error:
                current_app.logger.error(error)
                return InternalErrResp()

        resp = Message(False, "Insufficient permissions!")
        resp["error_reason"] = "insufficient_permissions"
        return resp, 403
示例#14
0
def upload_file(files, foldername, extensions):
    if "image" not in files:
        resp = Message(False, "File not found!")
        resp["error_reason"] = "file_404"
        return resp, 404

    file = files["image"]
    # Check if there is a filename
    if file.filename == "":
        resp = Message(False, "No file selected!")
        resp["error_reason"] = "filename"
        return resp, 403

    # Process if it passes validation
    allowed_extensions = set(extensions)
    if file and allowed_file(file.filename, allowed_extensions):
        # Get the filename
        filename = file.filename
        extension = "." + filename.split(".")[1]

        # Hash the file and limit to 32chars
        hashed_file = sha256(str(
            file.filename).encode("utf-8")).hexdigest()[:32]

        # Save it and attach the extension
        try:
            file.save(
                os.path.join(STATIC_FOLDER_PATH + foldername + "/",
                             hashed_file + extension))

            resp = Message(True, "Image uploaded.")
            resp["image_id"] = hashed_file + extension
            return resp, 201

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#15
0
    def get_chronological(query_limit):
        # Get Post IDs by latest creation (chronological order)

        # Get Posts info
        posts = Post.query.with_entities(
            Post.id, Post.created).limit(query_limit).all()

        post_info = load_info_many(posts)

        feed = uniq(x["id"] for x in sorted(
            post_info, key=lambda x: x["created"], reverse=True))

        resp = Message(True, "Post IDs sent.")
        resp["post_ids"] = feed
        return resp, 200
示例#16
0
def load_user(identififer):
    # If the user_id is an int then use id
    if type(identififer) == int:
        user = User.query.filter_by(id=identififer).first()

    # Use public id
    else:
        user = User.query.filter_by(public_id=identififer).first()

    if not user:
        resp = Message(False, "Current user does not exist!")
        resp["error_reason"] = "user_404"
        return resp, 404

    return user
示例#17
0
    def get_notification_ids(current_user):
        try:
            notifs = (Notification.query.filter_by(
                target_owner=current_user.id).with_entities(
                    Notification.id, Notification.timestamp).all())
            notification_info = notifications_schema.dump(notifs)

            ids = uniq(x["id"] for x in sorted(
                notification_info, key=lambda x: x["timestamp"], reverse=True))

            resp = Message(True, "Sent notification IDs.")
            resp["notif_ids"] = ids
            return resp, 200

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()
示例#18
0
    def register(data):
        try:
            # Assign the vars
            email = data["email"]
            username = data["username"]
            full_name = data["full_name"]
            password = data["password"]
            entry_key = data["entry_key"]

            # Check if email exists
            if len(email) == 0 or email is None:
                resp = Message(False, "Email is required!")
                resp["error_reason"] = "no_email"
                return resp, 403

            # Check if the email is being used
            if User.query.filter_by(email=email).first() is not None:
                resp = Message(False, "Email is being used!")
                resp["error_reason"] = "email_used"
                return resp, 403

            # Check if the email is valid
            elif not EMAIl_REGEX.match(email):
                resp = Message(False, "Invalid email!")
                resp["error_reason"] = "email_invalid"
                return resp, 403

            # Check if the username is empty
            if len(username) == 0 or username is None:
                resp = Message(False, "Username is required!")
                resp["error_reason"] = "username_none"
                return resp, 403

            # Check if the username is being used
            elif User.query.filter_by(
                    username=username.lower()).first() is not None:
                resp = Message(False, "Username is already taken!")
                resp["error_reason"] = "username_taken"
                return resp, 403

            # Check if the username is equal to or between 4 and 15
            elif not 4 <= len(username) <= 15:
                resp = Message(False, "Username length is invalid!")
                resp["error_reason"] = "username_invalid"
                return resp, 403

            # Check if the username is alpha numeric
            elif not username.isalnum():
                resp = Message(False, "Username is not alpha numeric.")
                resp["error_reason"] = "username_not_alphanum"
                return resp, 403

            # Verify the full name and if it exists
            if len(full_name) == 0 or full_name is None:
                full_name = None

            else:
                # Validate the full name
                # Remove any spaces so that it properly checks.
                if not full_name.replace(" ", "").isalpha():
                    resp = Message(False, "Name is not alphabetical!")
                    resp["error_reason"] = "name_nonalpha"
                    return resp, 403

                # Check if the full name is equal to or between 2 and 50
                elif not 2 <= len(full_name) <= 50:
                    resp = Message(False, "Name length is invalid!")
                    resp["error_reason"] = "name_invalid"
                    return resp, 403

                # Replace multiple spaces with one.
                # 'firstName    lastName' -> 'firstName lastName'
                re.sub(" +", " ", full_name)

            # Check if the entry key is right
            if entry_key != current_app.config["ENTRY_KEY"]:
                resp = Message(False, "Entry key is invalid!")
                resp["error_reason"] = "entry_key_invalid"
                return resp, 403

            # Create new user object
            new_user = User(
                public_id=str(uuid4().int)[:15],
                email=email,
                username=username.lower(),
                full_name=full_name,
                password=password,
                joined_date=datetime.now(),
            )

            # Add and commit the user to the database
            db.session.add(new_user)
            db.session.flush()

            # Get the user's info
            user_schema = UserSchema()
            user_info = user_schema.dump(new_user)

            # Save changes
            db.session.commit()

            # Remove private information from user info
            for info in private_info:
                del user_info[info]

            # Return success response
            access_token = create_access_token(identity=new_user.id)

            resp = Message(True, "User registered.")
            resp["access_token"] = access_token
            resp["user"] = user_info
            return resp, 201

        except Exception as error:
            current_app.logger.error(error)
            return InternalErrResp()