def send_message(username):
    user = g.user

    if user.forum_ban:
        return jsonify({
            'err': 1,
            'message': 'Oops, you are blocked from sending any messages. Awkward...'
        })

    body = request.form.get('body')

    to_user = User.query.outerjoin(Player).options(
        joinedload(User.player)
    ).filter(
        or_(Player.username == username, User.username == username)
    ).first()

    if to_user:
        to_player = to_user.player
    else:
        # for cases of messages sent to players with no users created yet
        to_player = Player.query.filter_by(username=username).first()

        if not to_player:
            rollbar.report_message('to_player None', request=request)
            return jsonify({
                'err': 1
            })

    if libmessages.is_sender_spamming(user, to_user, to_player):
        rollbar.report_message('User blocked from spamming messages', request=request, extra_data={
            'to_user_id': to_user.id if to_user else None,
            'to_player_id': to_player.id if to_player else None
        })
        return jsonify({
            'err': 1,
            'message': 'Whoa there, you sent too many messages recently! Try sending a bit later.'
        })

    message = Message(
        from_user=user,
        to_user=to_user,
        to_player=to_player,
        body=body,
        user_ip=request.remote_addr
    )
    message.save()

    notify_new_message(message)

    stats.incr('messages.created')

    return jsonify({
        'err': 0,
        'message': message.to_dict()
    })
def messages(username=None):
    user = g.user


    messages = []
    form = MessageForm()

    template_vars = {
        'form': form
    }

    other_user_id = None

    if username:
        to_user = User.query.outerjoin(Player).options(
            joinedload(User.player)
        ).filter(
            or_(Player.username == username, User.username == username)
        ).first()

        if to_user == user:
            # don't allow user to send messages to themselves
            return redirect(url_for('messages'))

        if to_user:
            other_user_id = to_user.id
            to_player = to_user.player
        else:
            # for cases of messages sent to players with no users created yet
            to_player = Player.query.filter_by(username=username).first()

            if not to_player:
                abort(404)

        if form.validate_on_submit():
            text = form.text.data

            # prevent spam
            recent_messages = Message.query.with_entities(Message.id).filter(
                Message.from_user == user,
                Message.sent_at > datetime.utcnow() - timedelta(minutes=MESSAGE_THROTTLE_PERIOD)
            ).all()

            if not app.config['DEBUG'] and len(recent_messages) > MESSAGE_THROTTLE_COUNT:
                flash('Whoa there, you sent too many messages recently! Try sending a bit later.', 'error')
            else:
                message = Message(from_user=user, to_user=to_user, to_player=to_player,
                                  body=text, user_ip=request.remote_addr)
                message.save()

                notify_new_message(message)

                return redirect(url_for('messages', username=username))

        if to_user:
            # If the username matches an existing user, use it for the message query
            recipient_filter = or_(
                and_(Message.from_user == user, Message.to_user == to_user),
                and_(Message.from_user == to_user, Message.to_user == user)
            )
        else:
            # Otherwise, use the player matched by the username for the message query
            recipient_filter = or_(
                and_(Message.from_user == user, Message.to_player == to_player),
                and_(Message.from_user == to_user, Message.to_user == user)
            )

        messages = Message.query.filter(
            recipient_filter
        ).options(
            joinedload(Message.from_user)
            .joinedload(User.player)
        ).options(
            joinedload(Message.to_user)
            .joinedload(User.player)
        ).options(
            joinedload(Message.to_player)
        ).order_by(
            Message.sent_at.desc()
        ).limit(40)

        # reverse to get newest at the bottom
        messages = list(messages)[::-1]

        for message in messages:
            if message.to_user == user and not message.seen_at:
                Message.query.filter_by(
                    to_user=user,
                    from_user=message.from_user,
                    seen_at=None
                ).update({
                    'seen_at': datetime.utcnow()
                })

                @after_this_request
                def commit(response):
                    db.session.commit()
                    return response

                break

    contacts = get_contact_list(user)

    if not username and not contacts:
        return redirect(url_for('new_message'))

    if username and not messages:
        # show new contact at the top that will be messaged
        contacts.insert(0, {
            'username': username
        })

    template_vars.update({
        'contacts': contacts,
        'messages': messages,
        'username': username,
        'other_user_id': other_user_id
    })

    return render_template('messages/index.html', **template_vars)
Example #3
0
def message_reply():
    api_key = app.config['MAILGUN_API_KEY']

    token = request.form.get('token')
    timestamp = request.form.get('timestamp')
    signature = request.form.get('signature')

    if not verify_mailgun_signature(api_key, token, timestamp, signature):
        abort(403)

    body = request.form.get('stripped-text')
    full_body = request.form.get('body-plain')
    sender = request.form.get('sender')

    # try to find the reply token of the original message
    match = re.search(r'--([^\s]+)-([^\s]+)-([^\s]+)--', full_body)

    if match:
        b64_from_user_id, b64_to_user_id, signature = match.groups()

        try:
            # swap to/from in the original message since this is a reply
            reply_to_user_id = base64.b64decode(b64_from_user_id)
            reply_from_user_id = base64.b64decode(b64_to_user_id)
        except Exception:
            rollbar.report_message('Message not sent via email - cannot parse token', level='warning', extra_data={
                'b64_from_user_id': b64_from_user_id,
                'b64_to_user_id': b64_to_user_id
            })
        else:
            if verify_message_reply_signature(reply_to_user_id, reply_from_user_id, signature):
                to_user = User.query.options(
                    joinedload(User.player)
                ).get(reply_to_user_id)

                from_user = User.query.options(
                    joinedload(User.player)
                ).get(reply_from_user_id)

                if to_user and from_user:
                    message = Message(
                        from_user=from_user,
                        to_user=to_user,
                        to_player=to_user.player,
                        body=body,
                        user_ip=request.remote_addr
                    )
                    message.save()

                    stats.incr('messages.created')

                    notify_new_message(message)

                    rollbar.report_message('Message successfully sent via email', level='debug', extra_data={
                        'from_user_id': from_user.id,
                        'to_user_id': to_user.id
                    })
                else:
                    rollbar.report_message('Message not sent via email - user not found', level='warning', extra_data={
                        'reply_from_user_id': reply_from_user_id,
                        'reply_to_user_id': reply_to_user_id
                    })
            else:
                rollbar.report_message('Message not sent via email - reply token signature mismatch', level='warning', extra_data={
                    'reply_from_user_id': reply_from_user_id,
                    'reply_to_user_id': reply_to_user_id,
                    'signature': signature
                })
    else:
        rollbar.report_message('Message not sent via email - token not found', level='warning', extra_data={
            'sender': sender,
            'full_body': full_body
        })

    return jsonify({})
Example #4
0
def send_message(username):
    user = g.user
    player = user.player

    if user.forum_ban or (player and player.banned):
        rollbar.report_message('User blocked from sending a message', level='warning', request=request)
        return jsonify({
            'err': 1,
            'message': 'Oops, you are blocked from sending any messages. Awkward...'
        })

    body = request.form.get('body')

    to_user = User.query.outerjoin(Player).options(
        joinedload(User.player)
    ).filter(
        or_(Player.username == username, User.username == username)
    ).first()

    if to_user:
        to_player = to_user.player
    else:
        # for cases of messages sent to players with no users created yet
        to_player = Player.query.filter_by(username=username).first()

        if not to_player:
            rollbar.report_message('to_player None', request=request)
            return jsonify({
                'err': 1
            })

    if libmessages.is_sender_spamming(user, to_user, to_player):
        can_post = libforums.can_user_post(user)

        rollbar.report_message('User blocked from spamming messages', request=request, extra_data={
            'to_user_id': to_user.id if to_user else None,
            'to_player_id': to_player.id if to_player else None,
            'can-Post': can_post
        })

        if not can_post and not user.forum_ban:
            player = user.player
            libplayer.ban_player(player, source='message_spamming', commit=False)

            ban = ForumBan(user_id=user.id)
            ban.save(commit=True)

        return jsonify({
            'err': 1,
            'message': 'Whoa there, you sent too many messages recently! Try sending a bit later.'
        })

    message = Message(
        from_user=user,
        to_user=to_user,
        to_player=to_player,
        body=body,
        user_ip=request.remote_addr
    )

    message.save()

    notify_new_message(message)

    stats.incr('messages.created')

    return jsonify({
        'err': 0,
        'message': message.to_dict()
    })
Example #5
0
def message_reply():
    api_key = app.config['MAILGUN_API_KEY']

    token = request.form.get('token')
    timestamp = request.form.get('timestamp')
    signature = request.form.get('signature')

    if not verify_mailgun_signature(api_key, token, timestamp, signature):
        abort(403)

    body = request.form.get('stripped-text')
    full_body = request.form.get('body-plain')
    sender = request.form.get('sender')

    # try to find the reply token of the original message
    match = re.search(r'--([^\s]+)-([^\s]+)-([^\s]+)--', full_body)

    if match:
        b64_from_user_id, b64_to_user_id, signature = match.groups()

        try:
            # swap to/from in the original message since this is a reply
            reply_to_user_id = base64.b64decode(b64_from_user_id)
            reply_from_user_id = base64.b64decode(b64_to_user_id)
        except Exception:
            rollbar.report_message(
                'Message not sent via email - cannot parse token',
                level='warning',
                extra_data={
                    'b64_from_user_id': b64_from_user_id,
                    'b64_to_user_id': b64_to_user_id
                })
        else:
            if verify_message_reply_signature(reply_to_user_id,
                                              reply_from_user_id, signature):
                to_user = User.query.options(joinedload(
                    User.player)).get(reply_to_user_id)

                from_user = User.query.options(joinedload(
                    User.player)).get(reply_from_user_id)

                if to_user and from_user:
                    message = Message(from_user=from_user,
                                      to_user=to_user,
                                      to_player=to_user.player,
                                      body=body,
                                      user_ip=request.remote_addr)
                    message.save()

                    stats.incr('messages.created')

                    notify_new_message(message)

                    rollbar.report_message(
                        'Message successfully sent via email',
                        level='debug',
                        extra_data={
                            'from_user_id': from_user.id,
                            'to_user_id': to_user.id
                        })
                else:
                    rollbar.report_message(
                        'Message not sent via email - user not found',
                        level='warning',
                        extra_data={
                            'reply_from_user_id': reply_from_user_id,
                            'reply_to_user_id': reply_to_user_id
                        })
            else:
                rollbar.report_message(
                    'Message not sent via email - reply token signature mismatch',
                    level='warning',
                    extra_data={
                        'reply_from_user_id': reply_from_user_id,
                        'reply_to_user_id': reply_to_user_id,
                        'signature': signature
                    })
    else:
        rollbar.report_message('Message not sent via email - token not found',
                               level='warning',
                               extra_data={
                                   'sender': sender,
                                   'full_body': full_body
                               })

    return jsonify({})
def send_message(username):
    user = g.user
    player = user.player

    if user.forum_ban or (player and player.banned):
        rollbar.report_message('User blocked from sending a message',
                               level='warning',
                               request=request)
        return jsonify({
            'err':
            1,
            'message':
            'Oops, you are blocked from sending any messages. Awkward...'
        })

    body = request.form.get('body')

    to_user = User.query.outerjoin(Player).options(joinedload(
        User.player)).filter(
            or_(Player.username == username,
                User.username == username)).first()

    if to_user:
        to_player = to_user.player
    else:
        # for cases of messages sent to players with no users created yet
        to_player = Player.query.filter_by(username=username).first()

        if not to_player:
            rollbar.report_message('to_player None', request=request)
            return jsonify({'err': 1})

    if libmessages.is_sender_spamming(user, to_user, to_player):
        can_post = libforums.can_user_post(user)

        rollbar.report_message('User blocked from spamming messages',
                               request=request,
                               extra_data={
                                   'to_user_id':
                                   to_user.id if to_user else None,
                                   'to_player_id':
                                   to_player.id if to_player else None,
                                   'can-Post': can_post
                               })

        if not can_post and not user.forum_ban:
            player = user.player
            libplayer.ban_player(player,
                                 source='message_spamming',
                                 commit=False)

            ban = ForumBan(user_id=user.id)
            ban.save(commit=True)

        return jsonify({
            'err':
            1,
            'message':
            'Whoa there, you sent too many messages recently! Try sending a bit later.'
        })

    message = Message(from_user=user,
                      to_user=to_user,
                      to_player=to_player,
                      body=body,
                      user_ip=request.remote_addr)

    message.save()

    notify_new_message(message)

    stats.incr('messages.created')

    return jsonify({'err': 0, 'message': message.to_dict()})