<commit_before>from base64 import urlsafe_b64encode
from datetime import datetime
from flask import Flask, request, session, redirect, render_template, url_for,\
                  flash
from flask_sqlalchemy import SQLAlchemy
from functools import wraps
from getwords import getwords
from hashlib import sha256
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from werkzeug.exceptions import HTTPException, BadRequest, NotFound, InternalServerError
import os
import string


app = Flask(__name__, static_url_path=os.environ.get('STATIC_PREFIX', '/static'))

app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'not secure brah')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///test.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)


association_table = db.Table('team_flags', db.Model.metadata,
    db.Column('team_id', db.Integer, db.ForeignKey('team.id')),
    db.Column('flag_id', db.Integer, db.ForeignKey('flag.id'))
)


class Flag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    hash = db.Column(db.String(64))
    points = db.Column(db.Integer)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    level = db.Column(db.Integer)
    teams = db.relationship('Team', secondary=association_table)


class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    order = db.Column(db.Integer)
    name = db.Column(db.String(20))
    levels = db.relationship('Flag', backref='category')


class Team(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), unique=True)
    password = db.Column(db.String(128))
    points = db.Column(db.Integer, default=0)
    flags = db.relationship('Flag', secondary=association_table)
    last_flag = db.Column(db.DateTime, server_default=db.func.now())


CSRF_BYTES = 36
@app.before_request
def create_csrf():
    """Generate a cryptographically secure CSRF token for every session."""
    if 'csrf_token' not in session:
        token = urlsafe_b64encode(os.urandom(CSRF_BYTES)).decode('utf-8')
        session['csrf_token'] = token


def ensure_csrf(token):
    """Show 400 Bad Request for a missing/incorrect CSRF token."""
    if token != session.get('csrf_token'):
        flash('Missing or incorrect CSRF token.')
        raise BadRequest()


@app.before_request
def check_csrf():
    """Enforce CSRF tokens on all POST requests.

    We're assuming that no requests use PUT or DELETE methods.
    """
    if request.method == 'POST':
        ensure_csrf(request.form.get('token'))


@app.errorhandler(400)
@app.errorhandler(403)
@app.errorhandler(404)
@app.errorhandler(405)
@app.errorhandler(500)
def handle_error(exc):
    if not isinstance(exc, HTTPException):
        exc = InternalServerError()
    return render_template('error.html', error=exc), exc.code


def require_auth(fn):
    @wraps(fn)
    def inner(*args, **kwargs):
        if 'team' not in session:
            flash('You must be logged in to a team to do that.', 'danger')
            return redirect(url_for('login_page'), code=303)
        return fn(*args, **kwargs)
    return inner


@app.route('/')
def home_page():
    teams = Team.query.order_by(Team.points.desc(), Team.last_flag).all()
    return render_template('home.html', teams=teams)


@app.route('/login/')
def login_page():
    return render_template('login.html')


@app.route('/about/')
def about_page():
    return render_template('about.html')


@app.route('/contact/')
def contact_page():
    return render_template('contact.html')


@app.route('/submit/')
@require_auth
def flag_page():
    return render_template('submit.html')


@app.route('/teams/<int:id>/')
def team_page(id):
    team = Team.query.filter_by(id=id).first()
    if team is None:
        raise NotFound()
    cat_query = Category.query.order_by(Category.order.asc())
    categories = [(cat.name, cat.levels) for cat in cat_query]
    return render_template('team.html', team=team, categories=categories)


@app.route('/teams', methods=['POST'])
def new_team():
    """Create a new team, with a generated password."""
    name = request.form.get('name', '')
    if not name:
        flash('You must supply a team name.', 'danger')
        return redirect(url_for('login_page'), code=303)
    if Team.query.filter(func.lower(Team.name) == name.lower()).count() > 0:
        flash('That team name is taken.', 'danger')
        return redirect(url_for('login_page'), code=303)

    password = <PASSWORD>()
    team = Team(name=name, password=password)
    db.session.add(team)
    db.session.commit()
    session['team'] = team.id
    flash('Team successfully created.', 'success')
    return redirect(url_for('team_page', id=team.id), code=303)


@app.route('/auth_team', methods=['POST'])
def auth_team():
    name = request.form.get('name', '')
    password = request.form.get('password', '')
    team = Team.query.filter(func.lower(Team.name) == name.lower()).first()

    if team is None:
        flash('No team exists with that name.', 'danger')
        return redirect(url_for('login_page'), code=303)
    if password != team.password:
        flash('Incorrect team password.', 'danger')
        return redirect(url_for('login_page'), code=303)

    session['team'] = team.id
    return redirect(url_for('team_page', id=team.id), code=303)


@app.route('/logout')
@require_auth
def logout():
    """Clear the session, and redirect to home."""
    ensure_csrf(request.args.get('token'))
    session.clear()
    return redirect(url_for('home_page'), code=303)


@app.route('/flags', methods=['POST'])
@require_auth
def submit_flag():
    flag = request.form.get('flag', '')
    flag_hash = sha256(flag.encode('utf-8')).hexdigest()<commit_msg>Safely compare our plaintext passwords<commit_after>from base64 import urlsafe_b64encode
from datetime import datetime
from flask import Flask, request, session, redirect, render_template, url_for,\
                  flash
from flask_sqlalchemy import SQLAlchemy
from functools import wraps
from getwords import getwords
from hashlib import sha256
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from werkzeug.exceptions import HTTPException, BadRequest, NotFound, InternalServerError
from werkzeug.security import safe_str_cmp
import os
import string


app = Flask(__name__, static_url_path=os.environ.get('STATIC_PREFIX', '/static'))

app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'not secure brah')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///test.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)


association_table = db.Table('team_flags', db.Model.metadata,
    db.Column('team_id', db.Integer, db.ForeignKey('team.id')),
    db.Column('flag_id', db.Integer, db.ForeignKey('flag.id'))
)


class Flag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    hash = db.Column(db.String(64))
    points = db.Column(db.Integer)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    level = db.Column(db.Integer)
    teams = db.relationship('Team', secondary=association_table)


class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    order = db.Column(db.Integer)
    name = db.Column(db.String(20))
    levels = db.relationship('Flag', backref='category')


class Team(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), unique=True)
    password = db.Column(db.String(128))
    points = db.Column(db.Integer, default=0)
    flags = db.relationship('Flag', secondary=association_table)
    last_flag = db.Column(db.DateTime, server_default=db.func.now())


CSRF_BYTES = 36
@app.before_request
def create_csrf():
    """Generate a cryptographically secure CSRF token for every session."""
    if 'csrf_token' not in session:
        token = urlsafe_b64encode(os.urandom(CSRF_BYTES)).decode('utf-8')
        session['csrf_token'] = token


def ensure_csrf(token):
    """Show 400 Bad Request for a missing/incorrect CSRF token."""
    if token != session.get('csrf_token'):
        flash('Missing or incorrect CSRF token.')
        raise BadRequest()


@app.before_request
def check_csrf():
    """Enforce CSRF tokens on all POST requests.

    We're assuming that no requests use PUT or DELETE methods.
    """
    if request.method == 'POST':
        ensure_csrf(request.form.get('token'))


@app.errorhandler(400)
@app.errorhandler(403)
@app.errorhandler(404)
@app.errorhandler(405)
@app.errorhandler(500)
def handle_error(exc):
    if not isinstance(exc, HTTPException):
        exc = InternalServerError()
    return render_template('error.html', error=exc), exc.code


def require_auth(fn):
    @wraps(fn)
    def inner(*args, **kwargs):
        if 'team' not in session:
            flash('You must be logged in to a team to do that.', 'danger')
            return redirect(url_for('login_page'), code=303)
        return fn(*args, **kwargs)
    return inner


@app.route('/')
def home_page():
    teams = Team.query.order_by(Team.points.desc(), Team.last_flag).all()
    return render_template('home.html', teams=teams)


@app.route('/login/')
def login_page():
    return render_template('login.html')


@app.route('/about/')
def about_page():
    return render_template('about.html')


@app.route('/contact/')
def contact_page():
    return render_template('contact.html')


@app.route('/submit/')
@require_auth
def flag_page():
    return render_template('submit.html')


@app.route('/teams/<int:id>/')
def team_page(id):
    team = Team.query.filter_by(id=id).first()
    if team is None:
        raise NotFound()
    cat_query = Category.query.order_by(Category.order.asc())
    categories = [(cat.name, cat.levels) for cat in cat_query]
    return render_template('team.html', team=team, categories=categories)


@app.route('/teams', methods=['POST'])
def new_team():
    """Create a new team, with a generated password."""
    name = request.form.get('name', '')
    if not name:
        flash('You must supply a team name.', 'danger')
        return redirect(url_for('login_page'), code=303)
    if Team.query.filter(func.lower(Team.name) == name.lower()).count() > 0:
        flash('That team name is taken.', 'danger')
        return redirect(url_for('login_page'), code=303)

    password = <PASSWORD>()
    team = Team(name=name, password=password)
    db.session.add(team)
    db.session.commit()
    session['team'] = team.id
    flash('Team successfully created.', 'success')
    return redirect(url_for('team_page', id=team.id), code=303)


@app.route('/auth_team', methods=['POST'])
def auth_team():
    name = request.form.get('name', '')
    password = request.form.get('password', '')
    team = Team.query.filter(func.lower(Team.name) == name.lower()).first()

    if team is None:
        flash('No team exists with that name.', 'danger')
        return redirect(url_for('login_page'), code=303)
    if not safe_str_cmp(password, team.password):
        flash('Incorrect team password.', 'danger')
        return redirect(url_for('login_page'), code=303)

    session['team'] = team.id
    return redirect(url_for('team_page', id=team.id), code=303)


@app.route('/logout')
@require_auth
def logout():
    """Clear the session, and redirect to home."""
    ensure_csrf(request.args.get('token'))
    session.clear()
    return redirect(url_for('home_page'), code=303)


@app.route('/flags', methods=['POST'])
@require_auth
def submit_flag():
    flag = request.form.get('flag', '')
    flag_hash = sha256(flag.encode('utf-8')).hexdigest()
{'fraction_non_alphanumeric': 0.1500686813186813, 'fraction_numerical': 0.01201923076923077, 'mean_word_length': 4.11369622475856, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4244192', 'n_tokens_mistral': 3883, 'n_tokens_neox': 3712, 'n_words': 846}