From da2537ff3b519ff02fb49f885c6da2a0e6b78a23 Mon Sep 17 00:00:00 2001 From: Sean Meyer Date: Mon, 18 May 2015 10:15:55 +0800 Subject: [PATCH 1/3] Admins can delete pages --- CTFd/admin.py | 7 ++++++ templates/admin/pages.html | 45 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/CTFd/admin.py b/CTFd/admin.py index a4f532a4..9182d1bd 100644 --- a/CTFd/admin.py +++ b/CTFd/admin.py @@ -155,6 +155,13 @@ def init_admin(app): pages = Pages.query.all() return render_template('admin/pages.html', routes=pages) + @app.route('/admin/page//delete', methods=['POST']) + @admins_only + def delete_page(pageroute): + page = Pages.query.filter_by(route=pageroute).first() + db.session.delete(page) + db.session.commit() + return '1' @app.route('/admin/hosts', methods=['GET']) @admins_only diff --git a/templates/admin/pages.html b/templates/admin/pages.html index 518113d6..1f04675c 100644 --- a/templates/admin/pages.html +++ b/templates/admin/pages.html @@ -3,16 +3,31 @@ {% block content %}

+
+

Delete Page

+
+ + +
+

Are you sure you want to delete ?

+ + +
+
+ × +
+ {% for route in routes %} - - + + + {% endfor %} @@ -25,4 +40,30 @@ {% endblock %} {% block scripts %} + {% endblock %} From db687b6c25c28b71fe2a808035dcd381ae26fbb4 Mon Sep 17 00:00:00 2001 From: Sean Meyer Date: Mon, 18 May 2015 11:31:43 +0800 Subject: [PATCH 2/3] enable max-attempts per challenge setting --- CTFd/admin.py | 7 +++++++ CTFd/challenges.py | 17 +++++++++++++++-- CTFd/views.py | 5 +++++ static/js/chalboard.js | 21 +++++++++++++++++++++ templates/admin/config.html | 5 +++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/CTFd/admin.py b/CTFd/admin.py index a4f532a4..c38c873e 100644 --- a/CTFd/admin.py +++ b/CTFd/admin.py @@ -71,6 +71,7 @@ def init_admin(app): ctf_name = set_config("ctf_name", request.form.get('ctf_name', None)) mg_api_key = set_config("mg_api_key", request.form.get('mg_api_key', None)) do_api_key = set_config("do_api_key", request.form.get('do_api_key', None)) + max_tries = set_config("max_tries", request.form.get('max_tries', None)) db_start = Config.query.filter_by(key='start').first() db_start.value = start @@ -96,6 +97,11 @@ def init_admin(app): if not do_api_key: set_config('do_api_key', None) + max_tries = get_config('max_tries') + if not max_tries: + set_config('max_tries', 0) + max_tries = 0 + start = get_config('start') if not start: set_config('start', None) @@ -120,6 +126,7 @@ def init_admin(app): db.session.close() return render_template('admin/config.html', ctf_name=ctf_name, start=start, end=end, + max_tries=max_tries, view_challenges_unregistered=view_challenges_unregistered, prevent_registration=prevent_registration, do_api_key=do_api_key, mg_api_key=mg_api_key, prevent_name_change=prevent_name_change) diff --git a/CTFd/challenges.py b/CTFd/challenges.py index 3c9ed2ee..d22abef6 100644 --- a/CTFd/challenges.py +++ b/CTFd/challenges.py @@ -1,6 +1,6 @@ from flask import current_app as app, render_template, request, redirect, abort, jsonify, json as json_mod, url_for, session -from CTFd.utils import ctftime, authed, unix_time, get_kpm, can_view_challenges, is_admin +from CTFd.utils import ctftime, authed, unix_time, get_kpm, can_view_challenges, is_admin, get_config from CTFd.models import db, Challenges, Files, Solves, WrongKeys, Keys import time @@ -58,7 +58,17 @@ def init_challenges(app): db.session.close() json = {'solves':[]} for x in solves: - json['solves'].append({'id':x.id, 'chal':x.chal.name, 'chalid':x.chalid,'team':x.teamid, 'value': x.chal.value, 'category':x.chal.category, 'time':unix_time(x.date)}) + json['solves'].append({ 'chal':x.chal.name, 'chalid':x.chalid,'team':x.teamid, 'value': x.chal.value, 'category':x.chal.category, 'time':unix_time(x.date)}) + return jsonify(json) + + @app.route('/maxattempts') + def attempts(): + chals = Challenges.query.add_columns('id').all() + json = {'maxattempts':[]} + for chal, chalid in chals: + fails = WrongKeys.query.filter_by(team=session['id'], chal=chalid).count() + if fails >= int(get_config("max_tries")) and int(get_config("max_tries")) > 0: + json['maxattempts'].append({'chalid':chalid}) return jsonify(json) @app.route('/fails/', methods=['GET']) @@ -82,9 +92,12 @@ def init_challenges(app): if not ctftime(): return redirect('/') if authed(): + fails = WrongKeys.query.filter_by(team=session['id'],chal=chalid).count() logger = logging.getLogger('keys') data = (time.strftime("%m/%d/%Y %X"), session['username'].encode('utf-8'), request.form['key'].encode('utf-8'), get_kpm(session['id'])) print "[{0}] {1} submitted {2} with kpm {3}".format(*data) + if fails >= int(get_config("max_tries")) and int(get_config("max_tries")) > 0: + return "4" #too many tries on this challenge if get_kpm(session['id']) > 10: wrong = WrongKeys(session['id'], chalid, request.form['key']) db.session.add(wrong) diff --git a/CTFd/views.py b/CTFd/views.py index 0ad7b00c..ecfb71f1 100644 --- a/CTFd/views.py +++ b/CTFd/views.py @@ -62,6 +62,10 @@ def init_views(app): html = request.form['html'] page = Pages('index', html) + #max attempts per challenge + max_tries = Config("max_tries",0) + + ## Start time start = Config('start', None) end = Config('end', None) @@ -77,6 +81,7 @@ def init_views(app): db.session.add(ctf_name) db.session.add(admin) db.session.add(page) + db.session.add(max_tries) db.session.add(start) db.session.add(end) db.session.add(view_challenges_unregistered) diff --git a/static/js/chalboard.js b/static/js/chalboard.js index 19fa28ae..90287e0c 100644 --- a/static/js/chalboard.js +++ b/static/js/chalboard.js @@ -105,6 +105,12 @@ function submitkey(chal, key, nonce) { $('#submit-key').css('background-color', '#e18728') $('#submit-key').prop('disabled', true) } + else if (data == 4){ // too many incorrect solves + $('#submit-key').text('Too many attempts.') + $('#submit-key').css('background-color', 'red') + $('#submit-key').prop('disabled', true) + } + marktoomanyattempts() marksolves() updatesolves() setTimeout(function(){ @@ -129,6 +135,20 @@ function marksolves() { }); } +function marktoomanyattempts() { + $.get('/maxattempts', function (data) { + maxattempts = $.parseJSON(JSON.stringify(data)); + for (var i = maxattempts['maxattempts'].length - 1; i >= 0; i--) { + id = maxattempts['maxattempts'][i].chalid + $('#challenges button[value="' + id + '"]').addClass('secondary') + $('#challenges button[value="' + id + '"]').css('background-color', '#FF9999') + }; + if (window.location.hash.length > 0){ + loadchalbyname(window.location.hash.substring(1)) + } + }); +} + function updatesolves(){ $.get('/chals/solves', function (data) { solves = $.parseJSON(JSON.stringify(data)); @@ -177,6 +197,7 @@ function loadchals() { $('#' + challenges['game'][i].category.replace(/ /g,"-")).append($('')); }; updatesolves() + marktoomanyattempts() marksolves() $('#challenges button').click(function (e) { diff --git a/templates/admin/config.html b/templates/admin/config.html index ddbbb10e..f5d6665d 100644 --- a/templates/admin/config.html +++ b/templates/admin/config.html @@ -12,6 +12,11 @@ +
+ + +
+
From d9394eda53bc180b961b8ce13fc208e8bf3ca950 Mon Sep 17 00:00:00 2001 From: Sean Meyer Date: Mon, 18 May 2015 12:25:38 +0800 Subject: [PATCH 3/3] fix least solved challenge statistic --- CTFd/admin.py | 2 +- templates/admin/statistics.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CTFd/admin.py b/CTFd/admin.py index a4f532a4..06890d5e 100644 --- a/CTFd/admin.py +++ b/CTFd/admin.py @@ -438,7 +438,7 @@ def init_admin(app): solve_count = db.session.query(db.func.count(Solves.id)).first()[0] challenge_count = db.session.query(db.func.count(Challenges.id)).first()[0] most_solved_chal = Solves.query.add_columns(db.func.count(Solves.chalid).label('solves')).group_by(Solves.chalid).order_by('solves DESC').first() - least_solved_chal = Solves.query.add_columns(db.func.count(Solves.chalid).label('solves')).group_by(Solves.chalid).order_by('solves ASC').first() + least_solved_chal = Challenges.query.add_columns(db.func.count(Solves.chalid).label('solves')).outerjoin(Solves).group_by(Challenges.id).order_by('solves ASC').first() db.session.close() diff --git a/templates/admin/statistics.html b/templates/admin/statistics.html index 45580cf6..64a87c35 100644 --- a/templates/admin/statistics.html +++ b/templates/admin/statistics.html @@ -13,7 +13,7 @@

Most solved: {{ most_solved[0].chal.name }} with {{ most_solved[1] }} solves

{% endif %} {% if least_solved %} -

Least solved: {{ least_solved[0].chal.name }} with {{ least_solved[1] }} solves

+

Least solved: {{ least_solved[0].name }} with {{ least_solved[1] }} solves

{% endif %}
RouteSettings
{{ route.route }}
{{ route.route }}