示例#1
0
def load(app):
    """load overrides for smart_city to work properly"""
    logger.setLevel(app.logger.getEffectiveLevel())
    app.db.create_all()
    register_plugin_assets_directory(
        app, base_path='/plugins/CTFd_SmartCity/assets')
    challenges.CHALLENGE_CLASSES['smart_city'] = SmartCity

    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'new-register.html')
    override_template('register.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-admin-team.html')
    override_template('admin/teams.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-setup.html')
    override_template('setup.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-team.html')
    override_template('teams.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-base.html')
    override_template('base.html', open(template_path).read())
    app.view_functions['auth.register'] = register_smart
    app.view_functions['challenges.chal'] = chal_custom
    app.view_functions['admin_teams.delete_team'] = delete_team_custom
    app.view_functions[
        'admin_teams.admin_create_team'] = admin_create_team_custom
    app.view_functions[
        'admin_teams.admin_teams_view'] = admin_teams_view_custom
    app.view_functions['views.setup'] = setup_custom
    app.view_functions['views.teams'] = teams_custom
示例#2
0
def test_override_template():
    """Does override_template work properly for regular themes"""
    app = create_ctfd()
    with app.app_context():
        override_template('login.html', 'LOGIN OVERRIDE')
        with app.test_client() as client:
            r = client.get('/login')
            assert r.status_code == 200
            output = r.get_data(as_text=True)
            assert 'LOGIN OVERRIDE' in output
示例#3
0
def test_override_template():
    """Does override_template work properly for regular themes"""
    app = create_ctfd()
    with app.app_context():
        override_template('login.html', 'LOGIN OVERRIDE')
        with app.test_client() as client:
            r = client.get('/login')
            assert r.status_code == 200
            output = r.get_data(as_text=True)
            assert 'LOGIN OVERRIDE' in output
示例#4
0
def test_admin_override_template():
    """Does override_template work properly for the admin panel"""
    app = create_ctfd()
    with app.app_context():
        override_template('admin/team.html', 'ADMIN TEAM OVERRIDE')

        client = login_as_user(app, name="admin", password="******")
        r = client.get('/admin/team/1')
        assert r.status_code == 200
        output = r.get_data(as_text=True)
        assert 'ADMIN TEAM OVERRIDE' in output
示例#5
0
def test_admin_override_template():
    """Does override_template work properly for the admin panel"""
    app = create_ctfd()
    with app.app_context():
        override_template('admin/team.html', 'ADMIN TEAM OVERRIDE')

        client = login_as_user(app, name="admin", password="******")
        r = client.get('/admin/team/1')
        assert r.status_code == 200
        output = r.get_data(as_text=True)
        assert 'ADMIN TEAM OVERRIDE' in output
def override_register_template():
    dir_path = path.dirname(path.realpath(__file__))
    template_path = None
    selected_option = utils.get_config('private_registration_option')

    if selected_option == 'token':
        template_path = '/templates/private-registration-token.html'
    elif selected_option == 'email':
        template_path = '/templates/private-registration-email.html'

    if template_path:
        template_path = dir_path + template_path
        with open(template_path, 'r') as register_template:
            override_template('register.html', register_template.read())
def load(app):
    app.db.create_all()

    classification = Blueprint('classification',
                               __name__,
                               template_folder='./')

    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'scoreboard.html')
    override_template('scoreboard.html', open(template_path).read())

    register_plugin_asset(app, asset_path='/plugins/classification/config.js')

    # Server side Configuration menu
    @classification.route('/admin/plugins/classification/',
                          methods=['GET', 'POST'])
    @utils.admins_only
    def classified():
        if request.method == 'POST':
            teamid = request.form['id']
            previous = Classification.query.filter_by(id=teamid)
            for x in previous:
                db.session.delete(x)

            errors = []
            classification = request.form['classification']

            if classification == 'other':
                classification = request.form['new_classification']

            classify = Classification(int(teamid), classification)
            db.session.add(classify)
            db.session.commit()
            db.session.close()

        if request.method == 'GET' or request.method == 'POST':

            classifications = Classification.query.all()

            teams = []
            scoring_teams = []
            standings = get_standings()

            # Competitors with a score
            for i, x in enumerate(standings):
                pushed = 0
                for classification in classifications:
                    if classification.teamid == x.teamid:
                        teams.append({
                            'id': x.teamid,
                            'name': x.name,
                            'class': classification.classification,
                            'score': x.score
                        })
                        pushed = 1
                        break
                scoring_teams.append(x.teamid)
                if (pushed == 0):
                    teams.append({
                        'id': x.teamid,
                        'name': x.name,
                        'class': '',
                        'score': x.score
                    })

            # Competitors with/without a score (limited to only without a score)
            for team in db.session.query(Teams.name, Teams.id,
                                         Teams.admin).all():
                if (team.admin == False):
                    pushed = 0
                    for classification in classifications:
                        if classification.teamid == team.id:
                            if (team.id not in scoring_teams):
                                teams.append({
                                    'id': team.id,
                                    'name': team.name,
                                    'class': classification.classification,
                                    'score': ''
                                })
                                pushed = 1
                    if (pushed == 0 and (team.id not in scoring_teams)):
                        teams.append({
                            'id': team.id,
                            'name': team.name,
                            'class': '',
                            'score': ''
                        })

            classf = []
            for clas in classifications:
                classf.append(clas.classification)
            classf = list(sorted(set(classf)))

            # -=- For TAMUctf, but can be left in without any problems -=-
            try:
                tamu_test()
                tamu = ["tamu"]
            except:
                tamu = []
            # -=-

            db.session.close()

            return render_template('config.html',
                                   teams=teams,
                                   classifications=classf,
                                   tamu=tamu)

    def get_standings(admin=False, count=None, classification=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,
                                Classification.classification
                            )\
                            .join(sumscores, Teams.id == sumscores.columns.teamid) \
                            .join(Classification, Teams.id == Classification.id) \
                            .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,
                                Classification.classification
                            )\
                            .join(sumscores, Teams.id == sumscores.columns.teamid) \
                            .join(Classification, Teams.id == Classification.id) \
                            .filter(Teams.banned == False) \
                            .order_by(sumscores.columns.score.desc(), sumscores.columns.date)

        if classification and count:
            # -=- For TAMUctf, but can be left in without any problems -=-
            try:
                tamu_test()
                c = Classification
                if (classification == "tamu"):
                    standings = standings_query.filter(
                        or_(c.classification == "U0", c.classification == "U1",
                            c.classification == "U2", c.classification == "U3",
                            c.classification == "U4", c.classification == "U5",
                            c.classification == "G5", c.classification == "G6",
                            c.classification == "G7", c.classification == "G8",
                            c.classification == "G9")).limit(count).all()
                elif (classification == "tamug"):
                    standings = standings_query.filter(
                        or_(c.classification == "G5", c.classification == "G6",
                            c.classification == "G7", c.classification == "G8",
                            c.classification == "G9")).limit(count).all()
                elif (classification == "tamuu"):
                    standings = standings_query.filter(
                        or_(c.classification == "U0", c.classification == "U1",
                            c.classification == "U2", c.classification == "U3",
                            c.classification == "U4",
                            c.classification == "U5")).limit(count).all()
                elif (classification == "U4"):
                    standings = standings_query.filter(
                        or_(c.classification == "U4",
                            c.classification == "U5")).limit(count).all()
                elif (classification == "tamum"):
                    standings = standings_query.filter(
                        or_(c.other == 3, c.other == 5, c.other == 7,
                            c.other == 8, c.other == 12, c.other == 10,
                            c.other == 15)).limit(count).all()
                elif (classification == "tamumc"):
                    standings = standings_query.filter(
                        or_(c.other == 3, c.other == 8, c.other == 10,
                            c.other == 15)).limit(count).all()
                elif (classification == "tamumr"):
                    standings = standings_query.filter(
                        or_(c.other == 5, c.other == 8, c.other == 12,
                            c.other == 15)).limit(count).all()
                elif (classification == "tamumd"):
                    standings = standings_query.filter(
                        or_(c.other == 7, c.other == 12, c.other == 10,
                            c.other == 15)).limit(count).all()
                else:
                    standings = standings_query.filter(
                        Classification.classification == classification).limit(
                            count).all()
            except:
                standings = standings_query.filter(
                    Classification.classification == classification).limit(
                        count).all()
            #-=-
        elif classification:
            # -=- For TAMUctf, but can be left in without any problems -=-
            try:
                tamu_test()
                c = Classification
                if (classification == "tamu"):
                    standings = standings_query.filter(
                        or_(c.classification == "U0", c.classification == "U1",
                            c.classification == "U2", c.classification == "U3",
                            c.classification == "U4", c.classification == "U5",
                            c.classification == "G5", c.classification == "G6",
                            c.classification == "G7", c.classification == "G8",
                            c.classification == "G9")).all()
                elif (classification == "tamug"):
                    standings = standings_query.filter(
                        or_(c.classification == "G5", c.classification == "G6",
                            c.classification == "G7", c.classification == "G8",
                            c.classification == "G9")).all()
                elif (classification == "tamuu"):
                    standings = standings_query.filter(
                        or_(c.classification == "U01",
                            c.classification == "U1", c.classification == "U2",
                            c.classification == "U3", c.classification == "U4",
                            c.classification == "U5")).all()
                elif (classification == "tamuu"):
                    standings = standings_query.filter(
                        or_(c.classification == "U4",
                            c.classification == "U5")).all()
                elif (classification == "tamum"):
                    standings = standings_query.filter(
                        or_(c.other == 3, c.other == 5, c.other == 7,
                            c.other == 8, c.other == 12, c.other == 10,
                            c.other == 15)).all()
                elif (classification == "tamumc"):
                    standings = standings_query.filter(
                        or_(c.other == 3, c.other == 8, c.other == 10,
                            c.other == 15)).all()
                elif (classification == "tamumr"):
                    standings = standings_query.filter(
                        or_(c.other == 5, c.other == 8, c.other == 12,
                            c.other == 15)).all()
                elif (classification == "tamumd"):
                    standings = standings_query.filter(
                        or_(c.other == 7, c.other == 12, c.other == 10,
                            c.other == 15)).all()
                else:
                    standings = standings_query.filter(
                        Classification.classification == classification).all()
            except:
                standings = standings_query.filter(
                    Classification.classification == classification).all()
            #-=-

        elif count:
            standings = standings_query.limit(count).all()
        else:
            standings = standings_query.all()

        return standings

    def scoreboard_view():
        classifications = []
        for classification in db.session.query(
                Classification.classification).distinct():
            classifications.append(classification[0])
        db.session.close()

        classifications = sorted(classifications, reverse=True)

        # -=- For TAMUctf, but can be left in without any problems -=-
        try:
            tamu_test()
            tamu = ["tamu"]
        except:
            tamu = []
        #-=-
        try:
            current_user_class = Classification.query.filter_by(
                id=session.get('id')).first().classification
        except:
            current_user_class = "ALL"
        try:
            current_user_other = Classification.query.filter_by(
                id=session.get('id')).first().other
        except:
            current_user_other = 0

        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(),
                               classifications=classifications,
                               tamu=tamu,
                               current_user_class=current_user_class,
                               current_user_other=current_user_other)

    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)

    @app.route('/scores/<classification>')
    def classified_scores(classification):
        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(classification=classification)

        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)

    @app.route('/top/<int:count>/<classification>')
    def classified_topteams(count, classification):
        json = {'places': {}}
        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, classification=classification)

        team_ids = [team.teamid for team in standings]

        solves = Solves.query.filter(Solves.teamid.in_(team_ids))
        awards = Awards.query.filter(Awards.teamid.in_(team_ids))

        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()

        for i, team in enumerate(team_ids):
            json['places'][i + 1] = {
                'id': standings[i].teamid,
                'name': standings[i].name,
                'solves': []
            }
            for solve in solves:
                if solve.teamid == team:
                    json['places'][i + 1]['solves'].append({
                        'chal':
                        solve.chalid,
                        'team':
                        solve.teamid,
                        'value':
                        solve.chal.value,
                        'time':
                        utils.unix_time(solve.date)
                    })
            for award in awards:
                if award.teamid == team:
                    json['places'][i + 1]['solves'].append({
                        'chal':
                        None,
                        'team':
                        award.teamid,
                        'value':
                        award.value,
                        'time':
                        utils.unix_time(award.date)
                    })
            json['places'][i + 1]['solves'] = sorted(
                json['places'][i + 1]['solves'], key=lambda k: k['time'])

        return jsonify(json)

    app.view_functions['scoreboard.scoreboard_view'] = scoreboard_view
    app.view_functions['scoreboard.scores'] = scores

    app.register_blueprint(classification)
示例#8
0
def load(app):
    app.db.create_all()
    register_plugin_assets_directory(app, base_path='/plugins/CCTFd/assets/')

    # create new challenge type
    CHALLENGE_CLASSES['community'] = CommunityChallenge

    # Replace templates
    dir_path = os.path.dirname(os.path.realpath(__file__))

    base_path = os.path.join(dir_path, 'community-base.html')
    create_path = os.path.join(dir_path, 'create.html')
    chal_path = os.path.join(dir_path, 'challenges.html')

    override_template('base.html', open(base_path).read())
    override_template('admin/chals/create.html', open(create_path).read())
    override_template('challenges.html', open(chal_path).read())

    # replace /chals route
    def chals():
        if not utils.is_admin():
            if not utils.ctftime():
                if utils.view_after_ctf():
                    pass
                else:
                    abort(403)

        if utils.get_config('verify_emails'):
            if utils.authed():
                if utils.is_admin() is False and utils.is_verified(
                ) is False:  # User is not confirmed
                    abort(403)

        if utils.user_can_view_challenges() and (utils.ctf_started()
                                                 or utils.is_admin()):
            teamid = session.get('id')
            chals = Challenges.query.filter(
                or_(Challenges.hidden != True,
                    Challenges.hidden == None)).order_by(
                        Challenges.value).all()

            json = {'game': []}
            for x in chals:
                tags = [
                    tag.tag for tag in Tags.query.add_columns('tag').filter_by(
                        chal=x.id).all()
                ]
                files = [
                    str(f.location)
                    for f in Files.query.filter_by(chal=x.id).all()
                ]
                unlocked_hints = set([
                    u.itemid for u in Unlocks.query.filter_by(model='hints',
                                                              teamid=teamid)
                ])
                hints = []
                for hint in Hints.query.filter_by(chal=x.id).all():
                    if hint.id in unlocked_hints or utils.ctf_ended():
                        hints.append({
                            'id': hint.id,
                            'cost': hint.cost,
                            'hint': hint.hint
                        })
                    else:
                        hints.append({'id': hint.id, 'cost': hint.cost})
                chal_type = get_chal_class(x.type)

                if chal_type == CommunityChallenge:
                    owner_id = CommunityChallengeModel.query.filter(
                        CommunityChallengeModel.id == x.id).first().owner
                else:
                    owner_id = 1

                owner = Teams.query.filter(Teams.id == owner_id).first().name
                own = (owner_id == session['id'])

                chal_data = {
                    'id': x.id,
                    'type': chal_type.name,
                    'name': x.name,
                    'value': x.value,
                    'description': x.description,
                    'category': x.category,
                    'files': files,
                    'tags': tags,
                    'hints': hints,
                    'owner': owner,
                    'own': own,
                    'template': chal_type.templates['modal'],
                    'script': chal_type.scripts['modal']
                }

                if own == True:
                    chal_data.update({'nonce': session.get('nonce')})

                json['game'].append(chal_data)

            db.session.close()
            return jsonify(json)
        else:
            db.session.close()
            abort(403)

    app.view_functions['challenges.chals'] = chals

    # create /community/chal_types route
    @app.route('/community/chal_types', methods=['GET'])
    def user_chal_types():
        data = {}
        for class_id in CHALLENGE_CLASSES:
            challenge_class = CHALLENGE_CLASSES.get(class_id)

            # only allow CommunityChallenge for non-admin users
            if not utils.is_admin() and challenge_class != CommunityChallenge:
                continue

            data[challenge_class.id] = {
                'id': challenge_class.id,
                'name': challenge_class.name,
                'templates': challenge_class.templates,
                'scripts': challenge_class.scripts,
            }

        return jsonify(data)

    # create /community/new route
    @app.route('/community/new', methods=['GET', 'POST'])
    def user_create_chal():
        if request.method == 'POST':
            chal_type = request.form['chaltype']
            chal_class = get_chal_class(chal_type)

            # do not allow non-admin users to create non-community challenges
            if not utils.is_admin() and chal_class != CommunityChallenge:
                abort(403)

            chal_class.create(request)
            return redirect(url_for('challenges.challenges_view'))
        else:
            return render_template('admin/chals/create.html',
                                   content=open(create_path).read())

    # create /community/update route
    @app.route('/community/update', methods=['POST'])
    def user_update_chal():
        challenge = Challenges.query.filter_by(
            id=request.form['id']).first_or_404()
        chal_class = get_chal_class(challenge.type)

        # only allow updating Community challenges
        if chal_class != CommunityChallenge:
            abort(403)

        # only allow updating the challenge if the user is the owner
        owner = CommunityChallengeModel.query.filter(
            CommunityChallengeModel.id == challenge.id).first().owner
        if owner != session['id']:
            abort(403)

        chal_class.update(challenge, request)
        return redirect(url_for('challenges.challenges_view'))
def load(app):
    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'scoreboard-matrix.html')
    override_template('scoreboard.html', open(template_path).read())

    matrix = Blueprint('matrix', __name__, static_folder='static')
    app.register_blueprint(matrix, url_prefix='/matrix')

    def get_standings():
        standings = scoreboard.get_standings()
        # TODO faster lookup here
        jstandings = []
        for team in standings:
            teamid = team[0]
            solves = db.session.query(Solves.chalid.label('chalid')).filter(Solves.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)
            solves = solves.all()
            jsolves = []
            for solve in solves:
                jsolves.append(solve.chalid)
            jstandings.append({'teamid':team.teamid, 'score':team.score, 'name':team.name,'solves':jsolves})
        db.session.close()
        return jstandings


    def get_challenges():
        if not utils.is_admin():
            if not utils.ctftime():
                if utils.view_after_ctf():
                    pass
                else:
                    return []
        if utils.user_can_view_challenges() and (utils.ctf_started() or utils.is_admin()):
            chals = db.session.query(
                    Challenges.id,
                    Challenges.name,
                    Challenges.category
                ).filter(or_(Challenges.hidden != True, Challenges.hidden == None)).all()
            jchals = []
            for x in chals:
                jchals.append({
                    'id':x.id,
                    'name':x.name,
                    'category':x.category
                })

            # Sort into groups
            categories = set(map(lambda x:x['category'], jchals))
            jchals = [j for c in categories for j in jchals if j['category'] == c]
            return jchals
        return []


    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(), challenges=get_challenges())

    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['name'], 'team': x['name'],
                'score': int(x['score']), 'solves':x['solves']})
        return jsonify(json)


    app.view_functions['scoreboard.scoreboard_view']  = scoreboard_view
    app.view_functions['scoreboard.scores']  = scores