enable max-attempts per challenge setting

selenium-screenshot-testing
Sean Meyer 2015-05-18 11:31:43 +08:00
parent 945e2148be
commit db687b6c25
5 changed files with 53 additions and 2 deletions

View File

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

View File

@ -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/<teamid>', 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)

View File

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

View File

@ -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($('<button value="' + challenges['game'][i].id + '">' + challenges['game'][i].value + '</button>'));
};
updatesolves()
marktoomanyattempts()
marksolves()
$('#challenges button').click(function (e) {

View File

@ -12,6 +12,11 @@
<input id='ctf_name' name='ctf_name' type='text' placeholder="CTF Name" {% if ctf_name is defined and ctf_name != None %}value="{{ ctf_name }}"{% endif %}>
</div>
<div class="row">
<label for="max_tries">Maximum Attempts Per Challenge (0 to disable):</label>
<input id='max_tries' name='max_tries' type='text' placeholder="0" {% if max_tries is defined and max_tries != None %}value="{{ max_tries }}"{% endif %}>
</div>
<div class="row">
<label for="start">Mailgun API Key:</label>
<input id='mg_api_key' name='mg_api_key' type='text' placeholder="Mailgun API Key" {% if mg_api_key is defined and mg_api_key != None %}value="{{ mg_api_key }}"{% endif %}>