예제 #1
0
def login():
    form = LoginForm()

    if form.validate_on_submit():
        username = request.form['username']
        password = request.form['password']
        next_path = request.form.get('next')

        username = username.strip()

        player = Player.query.filter_by(username=username).first()
        if player:
            user = player.user
        else:
            # TODO: check renames
            user = User.query.filter(
                or_(User.username == username, User.email == username)
            ).first()

        if user and user.check_password(password):
            if not user.session_key:
                user.generate_session_key(commit=False)

            session['user_session_key'] = user.session_key
            session.permanent = True

            if not user.last_login:
                session['first_login'] = True

            user.last_login = datetime.utcnow()
            user.save(commit=True)

            stats.incr('login.success')

            if user.mfa_login:
                session['mfa_stage'] = 'password-verified'
                return redirect(url_for('verify_mfa', next=next_path))

            flash('Successfully logged in', 'success')

            return redirect(next_path or url_for('index'))
        else:
            flash('Invalid username/password combination', 'error')

            stats.incr('login.invalid')

            AuditLog.create(
                AuditLog.INVALID_LOGIN,
                username=username,
                matched_user_id=user.id if user else None,
                ip=request.remote_addr,
                commit=True
            )

            return render_template('login.html', form=form), 401

    return render_template('login.html', form=form)
예제 #2
0
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()
    })
예제 #3
0
def login():
    form = LoginForm()

    if form.validate_on_submit():
        username = request.form['username']
        password = request.form['password']
        next_path = request.form.get('next')

        username = username.strip()

        player = Player.query.filter_by(username=username).first()
        if player:
            user = player.user
        else:
            # TODO: check renames
            user = User.query.filter(
                or_(User.username == username,
                    User.email == username)).first()

        if user and user.check_password(password):
            if not user.session_key:
                user.generate_session_key(commit=False)

            session['user_session_key'] = user.session_key
            session.permanent = True

            if not user.last_login:
                session['first_login'] = True

            user.last_login = datetime.utcnow()
            user.save(commit=True)

            stats.incr('login.success')

            if user.mfa_login:
                session['mfa_stage'] = 'password-verified'
                return redirect(url_for('verify_mfa', next=next_path))

            flash('Successfully logged in', 'success')

            return redirect(next_path or url_for('index'))
        else:
            flash('Invalid username/password combination', 'error')

            stats.incr('login.invalid')

            AuditLog.create(AuditLog.INVALID_LOGIN,
                            username=username,
                            matched_user_id=user.id if user else None,
                            ip=request.remote_addr,
                            commit=True)

            return render_template('login.html', form=form), 401

    return render_template('login.html', form=form)
예제 #4
0
def create_account(token):
    email_token = EmailToken.query.filter_by(token=token).first()

    result = _check_email_token(email_token, 'creation')
    if result:
        return result

    if g.user:
        rollbar.report_message('User already logged in when verifying creation email',
                               level='warning', request=request)

        session.pop('user_id', None)
        g.user = None

    form = VerifyEmailForm()

    player = Player.query.filter_by(uuid=email_token.uuid).first()
    email = email_token.email

    if form.validate_on_submit():
        password = form.password.data
        confirm_password = form.confirm_password.data

        if password != confirm_password:
            flash('Passwords do not match', 'error')
        else:
            email_token.date_redeemed = datetime.utcnow()

            user = User.create(player, password, email)

            session['user_id'] = user.id
            session['first_login'] = True
            session.permanent = True

            flash('Account created! You are now logged in', 'success')

            stats.incr('account.created')

            rollbar.report_message('Account created', level='info', request=request,
                                   extra_data={
                                       'user_id': user.id,
                                       'player_id': player.id,
                                       'username': player.username
                                   })

            return redirect(url_for('index'))

    return render_template('create_account.html', form=form, player=player,
                           email_token=email_token)
예제 #5
0
def login():
    form = LoginForm()

    if form.validate_on_submit():
        username = request.form['username']
        password = request.form['password']
        next_path = request.form.get('next')

        username = username.strip()

        player = Player.query.filter_by(username=username).first()
        if player:
            user = player.user
        else:
            user = User.query.filter(
                or_(User.username == username, User.email == username)
            ).first()

        if user and user.check_password(password):
            session['user_id'] = user.id
            session.permanent = True

            if not user.last_login:
                session['first_login'] = True

            user.last_login = datetime.utcnow()
            user.save(commit=True)

            stats.incr('login.success')

            flash('Successfully logged in', 'success')

            return redirect(next_path or url_for('index'))
        else:
            flash('Invalid username/password combination', 'error')

            stats.incr('login.invalid')

            return render_template('login.html', form=form), 401

    return render_template('login.html', form=form)
예제 #6
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({})
예제 #7
0
def _query_server(server, mojang_status):
    server_status = api.get_server_status(server) or {}

    player_stats = []

    players_to_sync_ban = Player.query.filter(
        Player.uuid.in_(server_status.get('banned_uuids', [])),
        Player.banned == False).all()

    if players_to_sync_ban:
        player_ids_to_sync_ban = [x.id for x in players_to_sync_ban]

        Player.query.filter(Player.id.in_(player_ids_to_sync_ban)).update(
            {
                'banned': True,
            }, synchronize_session=False)

        for player in players_to_sync_ban:
            AuditLog.create(AuditLog.PLAYER_BAN,
                            player_id=player.id,
                            username=player.username,
                            source='server_sync',
                            commit=False)

    online_player_ids = []
    for player_info in server_status.get('players', []):
        username = player_info['username']
        uuid = player_info['uuid']

        player = Player.query.options(joinedload(
            Player.titles)).filter_by(uuid=uuid).first()

        if player:
            if player.username != username:
                h.avoid_duplicate_username(username)

                player.set_username(username)
                player.save(commit=False)
        else:
            h.avoid_duplicate_username(username)

            player = Player(username=username, uuid=uuid)
            player.save(commit=False)

            statsd.incr('player.created')

        online_player_ids.append(player.id)

        last_activity = PlayerActivity.query.filter_by(
            server=server,
            player=player).order_by(PlayerActivity.timestamp.desc()).first()

        # if the last activity for this player is an 'exit' activity (or there isn't an activity),
        # create a new 'enter' activity since they just joined this minute
        if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES[
                'exit']:
            enter = PlayerActivity(
                server=server,
                player=player,
                activity_type=PLAYER_ACTIVITY_TYPES['enter'])
            enter.save(commit=False)

        if server.id == app.config['MAIN_SERVER_ID']:
            if player.banned:
                player.banned = False
                AuditLog.create(AuditLog.PLAYER_UNBAN,
                                player_id=player.id,
                                username=player.username,
                                source='server_sync',
                                commit=False)

            nickname_ansi = player_info.get('nickname_ansi')
            nickname = player_info.get('nickname')

            player.nickname_ansi = nickname_ansi
            player.nickname = nickname
            player.save(commit=False)

        ip = player_info.get('address')
        if ip:
            if not IPTracking.query.filter_by(ip=ip, player=player).first():
                existing_player_ip = IPTracking(ip=ip, player=player)
                existing_player_ip.save(commit=False)

            if geoip.is_nok(ip):
                libplayer.ban_player(player,
                                     with_ip=True,
                                     source='query',
                                     ip=ip,
                                     commit=False)

        stats = PlayerStats.query.filter_by(server=server,
                                            player=player).first()
        if not stats:
            stats = PlayerStats(server=server, player=player)

        stats.last_seen = datetime.utcnow()
        stats.pvp_logs = player_info.get('pvp_logs')
        stats.time_spent = (stats.time_spent or 0) + 1
        stats.save(commit=False)

        titles = [{
            'name': x.name,
            'broadcast': x.broadcast
        } for x in player.titles]

        player_stats.append({
            'username': player.username,
            'uuid': player.uuid,
            'minutes': stats.time_spent,
            'rank': stats.rank,
            'titles': titles
        })

    five_minutes_ago = datetime.utcnow() - timedelta(minutes=10)
    result = PlayerStats.query.filter(PlayerStats.server == server,
                                      PlayerStats.last_seen > five_minutes_ago)
    recent_player_ids = [x.player_id for x in result]

    # find all players that have recently left and insert an 'exit' activity for them
    # if their last activity was an 'enter'
    for player_id in set(recent_player_ids) - set(online_player_ids):
        latest_activity = PlayerActivity.query.filter_by(server=server, player_id=player_id)\
        .order_by(PlayerActivity.timestamp.desc()).first()

        if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES[
                'enter']:
            ex = PlayerActivity(server=server,
                                player_id=player_id,
                                activity_type=PLAYER_ACTIVITY_TYPES['exit'])
            ex.save(commit=False)

    player_count = server_status.get('numplayers', 0) or 0
    cpu_load = server_status.get('load', 0) or 0
    tps = server_status.get('tps', 0) or 0

    status = ServerStatus(server=server,
                          player_count=player_count,
                          cpu_load=cpu_load,
                          tps=tps)
    status.save(commit=True)

    api.send_stats(
        server, {
            'player_stats': player_stats,
            'session': mojang_status.session,
            'account': mojang_status.account,
            'auth': mojang_status.auth
        })

    _handle_groups(server, server_status.get('groups', []))
예제 #8
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()
    })
예제 #9
0
def _query_server(server, mojang_status):
    server_status = api.get_server_status(server) or {}
    
    player_stats = []

    players_to_sync_ban = Player.query.filter(
        Player.uuid.in_(server_status.get('banned_uuids', [])),
        Player.banned == False
    ).all()

    if players_to_sync_ban:
        player_ids_to_sync_ban = [x.id for x in players_to_sync_ban]

        Player.query.filter(
            Player.id.in_(player_ids_to_sync_ban)
        ).update({
            'banned': True,
        }, synchronize_session=False)

        for player in players_to_sync_ban:
            AuditLog.create(
                AuditLog.PLAYER_BAN,
                player_id=player.id,
                username=player.username,
                source='server_sync',
                commit=False
            )

    players = server_status.get('players', [])
    online_player_ids = []
    players_to_nok_ban = []
    for player_info in players:
        username = player_info['username']
        uuid = player_info['uuid']

        player = Player.query.options(
            joinedload(Player.titles)
        ).filter_by(uuid=uuid).first()

        if player:
            if player.username != username:
                h.avoid_duplicate_username(username)

                player.set_username(username)
                player.save(commit=False)
        else:
            h.avoid_duplicate_username(username)

            player = Player(username=username, uuid=uuid)
            player.save(commit=False)

            statsd.incr('player.created')
        
        online_player_ids.append(player.id)

        last_activity = PlayerActivity.query.filter_by(
            server=server, player=player
        ).order_by(
            PlayerActivity.timestamp.desc()
        ).first()
        
        # if the last activity for this player is an 'exit' activity (or there isn't an activity),
        # create a new 'enter' activity since they just joined this minute
        if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES['exit']:
            enter = PlayerActivity(server=server, player=player,
                                   activity_type=PLAYER_ACTIVITY_TYPES['enter'])
            enter.save(commit=False)

        if server.id == app.config['MAIN_SERVER_ID']:
            if player.banned:
                player.banned = False
                AuditLog.create(
                    AuditLog.PLAYER_UNBAN,
                    player_id=player.id,
                    username=player.username,
                    source='server_sync',
                    commit=False
                )

            nickname_ansi = player_info.get('nickname_ansi')
            nickname = player_info.get('nickname')

            player.nickname_ansi = nickname_ansi
            player.nickname = nickname
            player.save(commit=False)

        ip = player_info.get('address')
        if ip:
            if not IPTracking.query.filter_by(ip=ip, player=player).first():
                existing_player_ip = IPTracking(ip=ip, player=player)
                existing_player_ip.save(commit=False)

            if geoip.is_nok(ip):
                players_to_nok_ban.append((player, ip))

        stats = PlayerStats.query.filter_by(server=server, player=player).first()
        if not stats:
            stats = PlayerStats(server=server, player=player)

        stats.last_seen = datetime.utcnow()
        stats.pvp_logs = player_info.get('pvp_logs')
        stats.time_spent = (stats.time_spent or 0) + 1
        stats.save(commit=False)

        titles = [{'name': x.name, 'broadcast': x.broadcast} for x in player.titles]

        player_stats.append({
            'username': player.username,
            'uuid': player.uuid,
            'minutes': stats.time_spent,
            'rank': stats.rank,
            'titles': titles
        })

    if len(players) and (float(len(players_to_nok_ban)) / float(len(players))) < 0.5:
        for player, ip in players_to_nok_ban:
            libplayer.ban_player(player, with_ip=True, source='query', ip=ip, commit=False)

    five_minutes_ago = datetime.utcnow() - timedelta(minutes=10)
    result = PlayerStats.query.filter(PlayerStats.server == server,
                                      PlayerStats.last_seen > five_minutes_ago)
    recent_player_ids = [x.player_id for x in result]
    
    # find all players that have recently left and insert an 'exit' activity for them
    # if their last activity was an 'enter'
    for player_id in set(recent_player_ids) - set(online_player_ids):
        latest_activity = PlayerActivity.query.filter_by(server=server, player_id=player_id)\
        .order_by(PlayerActivity.timestamp.desc()).first()
        
        if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES['enter']:
            ex = PlayerActivity(server=server, player_id=player_id,
                                activity_type=PLAYER_ACTIVITY_TYPES['exit'])
            ex.save(commit=False)
    
    player_count = server_status.get('numplayers', 0) or 0
    cpu_load = server_status.get('load', 0) or 0
    tps = server_status.get('tps', 0) or 0
    
    status = ServerStatus(server=server, player_count=player_count, cpu_load=cpu_load, tps=tps)
    status.save(commit=True)

    api.send_stats(server, {
        'player_stats': player_stats,
        'session': mojang_status.session,
        'account': mojang_status.account,
        'auth': mojang_status.auth
    })

    _handle_groups(server, server_status.get('groups', []))
예제 #10
0
def create_account(token):
    email_token = EmailToken.query.filter_by(token=token).first()

    result = _check_email_token(email_token, 'creation')
    if result:
        return result

    if g.user:
        if g.user.forum_ban:
            session['forum_ban'] = True
            session.permanent = True
        if g.user.player.banned:
            session['player_ban'] = True
            session.permanent = True

        rollbar.report_message(
            'User already logged in when verifying creation email',
            level='warning',
            request=request,
            extra_data={
                'existing_forum_ban': bool(g.user.forum_ban),
                'existing_player_ban': bool(g.user.player.banned)
            })

        session.pop('user_session_key', None)
        g.user = None

    form = VerifyEmailForm()

    player = Player.query.filter_by(uuid=email_token.uuid).first()
    email = email_token.email

    if form.validate_on_submit():
        password = form.password.data
        confirm_password = form.confirm_password.data

        if password != confirm_password:
            flash('Passwords do not match', 'error')
        else:
            email_token.date_redeemed = datetime.utcnow()

            user = User.create(player, password, email)

            if session.get('forum_ban'):
                rollbar.report_message(
                    'Banning user associated with another forum banned user',
                    level='error',
                    request=request)
                ban = ForumBan(user_id=user.id)
                ban.save(commit=True)
            if session.get('player_ban'):
                rollbar.report_message(
                    'Banning player associated with another banned player',
                    level='error',
                    request=request)
                player.banned = True
                player.save(commit=True)

            session['user_session_key'] = user.session_key
            session['first_login'] = True
            session.permanent = True

            flash('Account created! You are now logged in', 'success')

            stats.incr('account.created')

            rollbar.report_message('Account created',
                                   level='info',
                                   request=request,
                                   extra_data={
                                       'user_id': user.id,
                                       'player_id': player.id,
                                       'username': player.username
                                   })

            return redirect(url_for('index'))

    return render_template('create_account.html',
                           form=form,
                           player=player,
                           email_token=email_token)
예제 #11
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({})
예제 #12
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()})
예제 #13
0
def create_account(token):
    email_token = EmailToken.query.filter_by(token=token).first()

    result = _check_email_token(email_token, 'creation')
    if result:
        return result

    if g.user:
        if g.user.forum_ban:
            session['forum_ban'] = True
            session.permanent = True
        if g.user.player.banned:
            session['player_ban'] = True
            session.permanent = True

        rollbar.report_message(
            'User already logged in when verifying creation email',
            level='warning',
            request=request,
            extra_data={
                'existing_forum_ban': bool(g.user.forum_ban),
                'existing_player_ban': bool(g.user.player.banned)
            }
        )

        session.pop('user_session_key', None)
        g.user = None

    form = VerifyEmailForm()

    player = Player.query.filter_by(uuid=email_token.uuid).first()
    email = email_token.email

    if form.validate_on_submit():
        password = form.password.data
        confirm_password = form.confirm_password.data

        if password != confirm_password:
            flash('Passwords do not match', 'error')
        else:
            email_token.date_redeemed = datetime.utcnow()

            user = User.create(player, password, email)

            if session.get('forum_ban'):
                rollbar.report_message(
                    'Banning user associated with another forum banned user',
                    level='error',
                    request=request
                )
                ban = ForumBan(user_id=user.id)
                ban.save(commit=True)
            if session.get('player_ban'):
                rollbar.report_message(
                    'Banning player associated with another banned player',
                    level='error',
                    request=request
                )
                player.banned = True
                player.save(commit=True)

            session['user_session_key'] = user.session_key
            session['first_login'] = True
            session.permanent = True

            flash('Account created! You are now logged in', 'success')

            stats.incr('account.created')

            rollbar.report_message(
                'Account created',
                level='info',
                request=request,
                extra_data={
                    'user_id': user.id,
                    'player_id': player.id,
                    'username': player.username
                }
            )

            return redirect(url_for('index'))

    return render_template('create_account.html', form=form, player=player,
                           email_token=email_token)