コード例 #1
0
def attempts():
    if not utils.user_can_view_challenges():
        return redirect(url_for('auth.login', next=request.path))
    chals = Challenges.query.add_columns('id').all()
    json = {'maxattempts': []}
    for chal, chalid in chals:
        fails = WrongKeys.query.filter_by(teamid=session['id'],
                                          chalid=chalid).count()
        if fails >= int(utils.get_config("max_tries")) and int(
                utils.get_config("max_tries")) > 0:
            json['maxattempts'].append({'chalid': chalid})
    return jsonify(json)
コード例 #2
0
ファイル: scoreboard.py プロジェクト: muhdzakirahmat/cft
def topteams(count):
    json = {'scores': {}}
    if utils.get_config('view_scoreboard_if_authed') and not utils.authed():
        return redirect(url_for('auth.login', next=request.path))
    if utils.hide_scores():
        return jsonify(json)

    if count > 20 or count < 0:
        count = 10

    standings = get_standings(count=count)

    for team in standings:
        solves = Solves.query.filter_by(teamid=team.teamid)
        awards = Awards.query.filter_by(teamid=team.teamid)

        freeze = utils.get_config('freeze')

        if freeze:
            solves = solves.filter(
                Solves.date < utils.unix_time_to_utc(freeze))
            awards = awards.filter(
                Awards.date < utils.unix_time_to_utc(freeze))

        solves = solves.all()
        awards = awards.all()

        json['scores'][team.name] = []
        for x in solves:
            json['scores'][team.name].append({
                'chal': x.chalid,
                'team': x.teamid,
                'value': x.chal.value,
                'time': utils.unix_time(x.date)
            })
        for award in awards:
            json['scores'][team.name].append({
                'chal':
                None,
                'team':
                award.teamid,
                'value':
                award.value,
                'time':
                utils.unix_time(award.date)
            })
        json['scores'][team.name] = sorted(json['scores'][team.name],
                                           key=lambda k: k['time'])
    return jsonify(json)
コード例 #3
0
def admin_pages_view(route):
    if request.method == 'GET' and request.args.get('mode') == 'create':
        return render_template('admin/editor.html')
    if route and request.method == 'GET':
        page = Pages.query.filter_by(route=route).first()
        return render_template('admin/editor.html', page=page)
    if route and request.method == 'POST':
        page = Pages.query.filter_by(route=route).first()
        errors = []
        html = request.form['html']
        route = request.form['route']
        if not route:
            errors.append('Missing URL route')
        if errors:
            page = Pages(html, '')
            return render_template('/admin/editor.html', page=page)
        if page:
            page.route = route
            page.html = html
            db.session.commit()
            db.session.close()
            return redirect(url_for('admin_pages.admin_pages_view'))
        page = Pages(route, html)
        db.session.add(page)
        db.session.commit()
        db.session.close()
        return redirect(url_for('admin_pages.admin_pages_view'))
    pages = Pages.query.all()
    return render_template('admin/pages.html',
                           routes=pages,
                           css=utils.get_config('css'))
コード例 #4
0
ファイル: scoreboard.py プロジェクト: muhdzakirahmat/cft
def scoreboard_view():
    if utils.get_config('view_scoreboard_if_authed') and not utils.authed():
        return redirect(url_for('auth.login', next=request.path))
    if utils.hide_scores():
        return render_template('scoreboard.html',
                               errors=['Scores are currently hidden'])
    standings = get_standings()
    return render_template('scoreboard.html',
                           teams=standings,
                           score_frozen=utils.is_scoreboard_frozen())
コード例 #5
0
ファイル: views.py プロジェクト: muhdzakirahmat/cft
def profile():
    if utils.authed():
        if request.method == "POST":
            errors = []

            name = request.form.get('name')
            email = request.form.get('email')

            user = Teams.query.filter_by(id=session['id']).first()

            if not utils.get_config('prevent_name_change'):
                names = Teams.query.filter_by(name=name).first()
                name_len = len(request.form['name']) == 0

            emails = Teams.query.filter_by(email=email).first()
            valid_email = re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", email)

            if ('password' in request.form.keys() and not len(request.form['password']) == 0) and \
                    (not bcrypt_sha256.verify(request.form.get('confirm').strip(), user.password)):
                errors.append("Your old password doesn't match what we have.")
            if not valid_email:
                errors.append("That email doesn't look right")
            if not utils.get_config('prevent_name_change') and names and name != session['username']:
                errors.append('That team name is already taken')
            if emails and emails.id != session['id']:
                errors.append('That email has already been used')
            if not utils.get_config('prevent_name_change') and name_len:
                errors.append('Pick a longer team name')

            if len(errors) > 0:
                return render_template('profile.html', name=name, email=email, errors=errors)
            else:
                team = Teams.query.filter_by(id=session['id']).first()
                if not utils.get_config('prevent_name_change'):
                    team.name = name
                if team.email != email.lower():
                    team.email = email.lower()
                    if utils.get_config('verify_emails'):
                        team.verified = False
                session['username'] = team.name

                if 'password' in request.form.keys() and not len(request.form['password']) == 0:
                    team.password = bcrypt_sha256.encrypt(request.form.get('password'))
                db.session.commit()
                db.session.close()
                return redirect(url_for('views.profile'))
        else:
            user = Teams.query.filter_by(id=session['id']).first()
            name = user.name
            email = user.email
            prevent_name_change = utils.get_config('prevent_name_change')
            confirm_email = utils.get_config('verify_emails') and not user.verified
            return render_template('profile.html', name=name, email=email, prevent_name_change=prevent_name_change, confirm_email=confirm_email)
    else:
        return redirect(url_for('auth.login'))
コード例 #6
0
def solves(teamid=None):
    solves = None
    awards = None
    if teamid is None:
        if utils.is_admin():
            solves = Solves.query.filter_by(teamid=session['id']).all()
        elif utils.user_can_view_challenges():
            if utils.authed():
                solves = Solves.query.join(Teams,
                                           Solves.teamid == Teams.id).filter(
                                               Solves.teamid == session['id'],
                                               Teams.banned == False).all()
            else:
                return jsonify({'solves': []})
        else:
            return redirect(url_for('auth.login', next='solves'))
    else:
        solves = Solves.query.filter_by(teamid=teamid)
        awards = Awards.query.filter_by(teamid=teamid)

        freeze = utils.get_config('freeze')
        if freeze:
            freeze = utils.unix_time_to_utc(freeze)
            if teamid != session.get('id'):
                solves = solves.filter(Solves.date < freeze)
                awards = awards.filter(Awards.date < freeze)

        solves = solves.all()
        awards = awards.all()
    db.session.close()
    json = {'solves': []}
    for solve in solves:
        json['solves'].append({
            'chal': solve.chal.name,
            'chalid': solve.chalid,
            'team': solve.teamid,
            'value': solve.chal.value,
            'category': solve.chal.category,
            'time': utils.unix_time(solve.date)
        })
    if awards:
        for award in awards:
            json['solves'].append({
                'chal': award.name,
                'chalid': None,
                'team': award.teamid,
                'value': award.value,
                'category': award.category or "Award",
                'time': utils.unix_time(award.date)
            })
    json['solves'].sort(key=lambda k: k['time'])
    return jsonify(json)
コード例 #7
0
ファイル: views.py プロジェクト: muhdzakirahmat/cft
def teams(page):
    page = abs(int(page))
    results_per_page = 50
    page_start = results_per_page * (page - 1)
    page_end = results_per_page * (page - 1) + results_per_page

    if utils.get_config('verify_emails'):
        count = Teams.query.filter_by(verified=True, banned=False).count()
        teams = Teams.query.filter_by(verified=True, banned=False).slice(page_start, page_end).all()
    else:
        count = Teams.query.filter_by(banned=False).count()
        teams = Teams.query.filter_by(banned=False).slice(page_start, page_end).all()
    pages = int(count / results_per_page) + (count % results_per_page > 0)
    return render_template('teams.html', teams=teams, team_pages=pages, curr_page=page)
コード例 #8
0
ファイル: scoreboard.py プロジェクト: muhdzakirahmat/cft
def get_standings(admin=False, count=None):
    scores = db.session.query(
        Solves.teamid.label('teamid'),
        db.func.sum(Challenges.value).label('score'),
        db.func.max(Solves.date).label('date')).join(Challenges).group_by(
            Solves.teamid)

    awards = db.session.query(Awards.teamid.label('teamid'),
                              db.func.sum(Awards.value).label('score'),
                              db.func.max(Awards.date).label('date')).group_by(
                                  Awards.teamid)

    freeze = utils.get_config('freeze')
    if not admin and freeze:
        scores = scores.filter(Solves.date < utils.unix_time_to_utc(freeze))
        awards = awards.filter(Awards.date < utils.unix_time_to_utc(freeze))

    results = union_all(scores, awards).alias('results')

    sumscores = db.session.query(
        results.columns.teamid,
        db.func.sum(results.columns.score).label('score'),
        db.func.max(results.columns.date).label('date')).group_by(
            results.columns.teamid).subquery()

    if admin:
        standings_query = db.session.query(
                            Teams.id.label('teamid'),
                            Teams.name.label('name'),
                            Teams.banned, sumscores.columns.score
                        )\
                        .join(sumscores, Teams.id == sumscores.columns.teamid) \
                        .order_by(sumscores.columns.score.desc(), sumscores.columns.date)
    else:
        standings_query = db.session.query(
                            Teams.id.label('teamid'),
                            Teams.name.label('name'),
                            sumscores.columns.score
                        )\
                        .join(sumscores, Teams.id == sumscores.columns.teamid) \
                        .filter(Teams.banned == False) \
                        .order_by(sumscores.columns.score.desc(), sumscores.columns.date)

    if count is None:
        standings = standings_query.all()
    else:
        standings = standings_query.limit(count).all()
    db.session.close()
    return standings
コード例 #9
0
ファイル: views.py プロジェクト: muhdzakirahmat/cft
def team(teamid):
    if utils.get_config('view_scoreboard_if_utils.authed') and not utils.authed():
        return redirect(url_for('auth.login', next=request.path))
    errors = []
    freeze = utils.get_config('freeze')
    user = Teams.query.filter_by(id=teamid).first_or_404()
    solves = Solves.query.filter_by(teamid=teamid)
    awards = Awards.query.filter_by(teamid=teamid)

    place = user.place()
    score = user.score()

    if freeze:
        freeze = utils.unix_time_to_utc(freeze)
        if teamid != session.get('id'):
            solves = solves.filter(Solves.date < freeze)
            awards = awards.filter(Awards.date < freeze)

    solves = solves.all()
    awards = awards.all()

    db.session.close()

    if utils.hide_scores() and teamid != session.get('id'):
        errors.append('Scores are currently hidden')

    if errors:
        return render_template('team.html', team=user, errors=errors)

    if request.method == 'GET':
        return render_template('team.html', solves=solves, awards=awards, team=user, score=score, place=place, score_frozen=utils.is_scoreboard_frozen())
    elif request.method == 'POST':
        json = {'solves': []}
        for x in solves:
            json['solves'].append({'id': x.id, 'chal': x.chalid, 'team': x.teamid})
        return jsonify(json)
コード例 #10
0
ファイル: scoreboard.py プロジェクト: muhdzakirahmat/cft
def scores():
    json = {'standings': []}
    if utils.get_config('view_scoreboard_if_authed') and not utils.authed():
        return redirect(url_for('auth.login', next=request.path))
    if utils.hide_scores():
        return jsonify(json)

    standings = get_standings()

    for i, x in enumerate(standings):
        json['standings'].append({
            'pos': i + 1,
            'id': x.teamid,
            'team': x.name,
            'score': int(x.score)
        })
    return jsonify(json)
コード例 #11
0
def challenges_view():
    errors = []
    start = utils.get_config('start') or 0
    end = utils.get_config('end') or 0
    if not utils.is_admin():  # User is not an admin
        if not utils.ctftime():
            # It is not CTF time
            if utils.view_after_ctf(
            ):  # But we are allowed to view after the CTF ends
                pass
            else:  # We are NOT allowed to view after the CTF ends
                if utils.get_config('start') and not utils.ctf_started():
                    errors.append('{} has not started yet'.format(
                        utils.ctf_name()))
                if (utils.get_config('end')
                        and utils.ctf_ended()) and not utils.view_after_ctf():
                    errors.append('{} has ended'.format(utils.ctf_name()))
                return render_template('chals.html',
                                       errors=errors,
                                       start=int(start),
                                       end=int(end))
        if utils.get_config('verify_emails') and not utils.is_verified(
        ):  # User is not confirmed
            return redirect(url_for('auth.confirm_user'))
    if utils.user_can_view_challenges():  # Do we allow unauthenticated users?
        if utils.get_config('start') and not utils.ctf_started():
            errors.append('{} has not started yet'.format(utils.ctf_name()))
        if (utils.get_config('end')
                and utils.ctf_ended()) and not utils.view_after_ctf():
            errors.append('{} has ended'.format(utils.ctf_name()))
        return render_template('chals.html',
                               errors=errors,
                               start=int(start),
                               end=int(end))
    else:
        return redirect(url_for('auth.login', next='challenges'))
コード例 #12
0
ファイル: views.py プロジェクト: muhdzakirahmat/cft
def custom_css():
    return Response(utils.get_config('css'), mimetype='text/css')
コード例 #13
0
def create_app(config='unit6.config.Config'):
    app = Flask(__name__)
    with app.app_context():
        app.config.from_object(config)
        app.jinja_loader = ThemeLoader(os.path.join(app.root_path,
                                                    app.template_folder),
                                       followlinks=True)

        from unit6.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking

        url = make_url(app.config['SQLALCHEMY_DATABASE_URI'])
        if url.drivername == 'postgres':
            url.drivername = 'postgresql'

        ## Creates database if the database database does not exist
        if not database_exists(url):
            create_database(url)

        ## Register database
        db.init_app(app)

        ## This creates tables instead of db.create_all()
        ## Allows migrations to happen properly

        ## Alembic sqlite support is lacking so we should just create_all anyway
        if url.drivername.startswith('sqlite'):
            db.create_all()

        app.db = db

        cache.init_app(app)
        app.cache = cache

        version = utils.get_config('ctf_version')

        if not version:  ## Upgrading from an unversioned unit6
            utils.set_config('ctf_version', __version__)

        if version and (StrictVersion(version) < StrictVersion(__version__)
                        ):  ## Upgrading from an older version of unit6
            print("/*\\ unit6 has updated and must update the database! /*\\")
            print("/*\\ Please backup your database before proceeding! /*\\")
            print(
                "/*\\ unit6 maintainers are not responsible for any data loss! /*\\"
            )
            if input('Run database migrations (Y/N)').lower().strip() == 'y':
                migrate_stamp()
                migrate_upgrade()
                utils.set_config('ctf_version', __version__)
            else:
                print('/*\\ Ignored database migrations... /*\\')
                exit()

        if not utils.get_config('ctf_theme'):
            utils.set_config('ctf_theme', 'original')

        from unit6.views import views
        from unit6.challenges import challenges
        from unit6.scoreboard import scoreboard
        from unit6.auth import auth
        from unit6.admin import admin, admin_statistics, admin_challenges, admin_pages, admin_scoreboard, admin_containers, admin_keys, admin_teams
        from unit6.utils import init_utils, init_errors, init_logs

        init_utils(app)
        init_errors(app)
        init_logs(app)

        app.register_blueprint(views)
        app.register_blueprint(challenges)
        app.register_blueprint(scoreboard)
        app.register_blueprint(auth)

        app.register_blueprint(admin)
        app.register_blueprint(admin_statistics)
        app.register_blueprint(admin_challenges)
        app.register_blueprint(admin_teams)
        app.register_blueprint(admin_scoreboard)
        app.register_blueprint(admin_keys)
        app.register_blueprint(admin_containers)
        app.register_blueprint(admin_pages)

        from unit6.plugins import init_plugins

        init_plugins(app)

        return app
コード例 #14
0
 def get_source(self, environment, template):
     if template.startswith('admin/'):
         return super(ThemeLoader, self).get_source(environment, template)
     theme = utils.get_config('ctf_theme')
     template = "/".join([theme, template])
     return super(ThemeLoader, self).get_source(environment, template)
コード例 #15
0
ファイル: __init__.py プロジェクト: muhdzakirahmat/cft
def admin_config():
    if request.method == "POST":
        start = None
        end = None
        freeze = None
        if request.form.get('start'):
            start = int(request.form['start'])
        if request.form.get('end'):
            end = int(request.form['end'])
        if request.form.get('freeze'):
            freeze = int(request.form['freeze'])

        try:
            view_challenges_unregistered = bool(request.form.get('view_challenges_unregistered', None))
            view_scoreboard_if_authed = bool(request.form.get('view_scoreboard_if_authed', None))
            hide_scores = bool(request.form.get('hide_scores', None))
            prevent_registration = bool(request.form.get('prevent_registration', None))
            prevent_name_change = bool(request.form.get('prevent_name_change', None))
            view_after_ctf = bool(request.form.get('view_after_ctf', None))
            verify_emails = bool(request.form.get('verify_emails', None))
            mail_tls = bool(request.form.get('mail_tls', None))
            mail_ssl = bool(request.form.get('mail_ssl', None))
        except (ValueError, TypeError):
            view_challenges_unregistered = None
            view_scoreboard_if_authed = None
            hide_scores = None
            prevent_registration = None
            prevent_name_change = None
            view_after_ctf = None
            verify_emails = None
            mail_tls = None
            mail_ssl = None
        finally:
            view_challenges_unregistered = utils.set_config('view_challenges_unregistered', view_challenges_unregistered)
            view_scoreboard_if_authed = utils.set_config('view_scoreboard_if_authed', view_scoreboard_if_authed)
            hide_scores = utils.set_config('hide_scores', hide_scores)
            prevent_registration = utils.set_config('prevent_registration', prevent_registration)
            prevent_name_change = utils.set_config('prevent_name_change', prevent_name_change)
            view_after_ctf = utils.set_config('view_after_ctf', view_after_ctf)
            verify_emails = utils.set_config('verify_emails', verify_emails)
            mail_tls = utils.set_config('mail_tls', mail_tls)
            mail_ssl = utils.set_config('mail_ssl', mail_ssl)

        mail_server = utils.set_config("mail_server", request.form.get('mail_server', None))
        mail_port = utils.set_config("mail_port", request.form.get('mail_port', None))

        mail_username = utils.set_config("mail_username", request.form.get('mail_username', None))
        mail_password = utils.set_config("mail_password", request.form.get('mail_password', None))

        ctf_name = utils.set_config("ctf_name", request.form.get('ctf_name', None))
        ctf_theme = utils.set_config("ctf_theme", request.form.get('ctf_theme', None))

        mailfrom_addr = utils.set_config("mailfrom_addr", request.form.get('mailfrom_addr', None))
        mg_base_url = utils.set_config("mg_base_url", request.form.get('mg_base_url', None))
        mg_api_key = utils.set_config("mg_api_key", request.form.get('mg_api_key', None))

        db_freeze = utils.set_config("freeze", freeze)

        db_start = Config.query.filter_by(key='start').first()
        db_start.value = start

        db_end = Config.query.filter_by(key='end').first()
        db_end.value = end

        db.session.add(db_start)
        db.session.add(db_end)

        db.session.commit()
        db.session.close()
        with app.app_context():
            cache.clear()
        return redirect(url_for('admin.admin_config'))

    with app.app_context():
        cache.clear()
    ctf_name = utils.get_config('ctf_name')
    ctf_theme = utils.get_config('ctf_theme')
    hide_scores = utils.get_config('hide_scores')

    mail_server = utils.get_config('mail_server')
    mail_port = utils.get_config('mail_port')
    mail_username = utils.get_config('mail_username')
    mail_password = utils.get_config('mail_password')

    mailfrom_addr = utils.get_config('mailfrom_addr')
    mg_api_key = utils.get_config('mg_api_key')
    mg_base_url = utils.get_config('mg_base_url')

    view_after_ctf = utils.get_config('view_after_ctf')
    start = utils.get_config('start')
    end = utils.get_config('end')
    freeze = utils.get_config('freeze')

    mail_tls = utils.get_config('mail_tls')
    mail_ssl = utils.get_config('mail_ssl')

    view_challenges_unregistered = utils.get_config('view_challenges_unregistered')
    view_scoreboard_if_authed = utils.get_config('view_scoreboard_if_authed')
    prevent_registration = utils.get_config('prevent_registration')
    prevent_name_change = utils.get_config('prevent_name_change')
    verify_emails = utils.get_config('verify_emails')

    db.session.commit()
    db.session.close()

    themes = utils.get_themes()
    themes.remove(ctf_theme)

    return render_template('admin/config.html',
                           ctf_name=ctf_name,
                           ctf_theme_config=ctf_theme,
                           start=start,
                           end=end,
                           freeze=freeze,
                           hide_scores=hide_scores,
                           mail_server=mail_server,
                           mail_port=mail_port,
                           mail_username=mail_username,
                           mail_password=mail_password,
                           mail_tls=mail_tls,
                           mail_ssl=mail_ssl,
                           view_challenges_unregistered=view_challenges_unregistered,
                           view_scoreboard_if_authed=view_scoreboard_if_authed,
                           prevent_registration=prevent_registration,
                           mailfrom_addr=mailfrom_addr,
                           mg_base_url=mg_base_url,
                           mg_api_key=mg_api_key,
                           prevent_name_change=prevent_name_change,
                           verify_emails=verify_emails,
                           view_after_ctf=view_after_ctf,
                           themes=themes)