mirror of https://github.com/JohnHammond/CTFd.git
Closes #82
parent
44d1ea300b
commit
9c1f1696ec
|
@ -2,6 +2,7 @@ from flask import render_template, request, redirect, abort, jsonify, url_for, s
|
||||||
from CTFd.utils import sha512, is_safe_url, authed, admins_only, is_admin, unix_time, unix_time_millis, get_config, set_config, sendmail, rmdir
|
from CTFd.utils import sha512, is_safe_url, authed, admins_only, is_admin, unix_time, unix_time_millis, get_config, set_config, sendmail, rmdir
|
||||||
from CTFd.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking, Pages, Config, DatabaseError
|
from CTFd.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking, Pages, Config, DatabaseError
|
||||||
from itsdangerous import TimedSerializer, BadTimeSignature
|
from itsdangerous import TimedSerializer, BadTimeSignature
|
||||||
|
from sqlalchemy.sql import and_, or_, not_
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
from socket import inet_aton, inet_ntoa
|
from socket import inet_aton, inet_ntoa
|
||||||
from passlib.hash import bcrypt_sha256
|
from passlib.hash import bcrypt_sha256
|
||||||
|
@ -197,9 +198,21 @@ def admin_chals():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
chals = Challenges.query.add_columns('id', 'name', 'value', 'description', 'category').order_by(Challenges.value).all()
|
chals = Challenges.query.add_columns('id', 'name', 'value', 'description', 'category').order_by(Challenges.value).all()
|
||||||
|
|
||||||
|
teams_with_points = db.session.query(Solves.teamid, Teams.name).join(Teams).filter(
|
||||||
|
Teams.banned == None).group_by(
|
||||||
|
Solves.teamid).count()
|
||||||
|
|
||||||
json_data = {'game':[]}
|
json_data = {'game':[]}
|
||||||
for x in chals:
|
for x in chals:
|
||||||
json_data['game'].append({'id':x[1], 'name':x[2], 'value':x[3], 'description':x[4], 'category':x[5]})
|
solve_count = Solves.query.filter_by(chalid=x[1]).count()
|
||||||
|
json_data['game'].append({
|
||||||
|
'id': x[1],
|
||||||
|
'name': x[2],
|
||||||
|
'value': x[3],
|
||||||
|
'description': x[4],
|
||||||
|
'category': x[5],
|
||||||
|
'percentage_solved': (float(solve_count) / float(teams_with_points))
|
||||||
|
})
|
||||||
|
|
||||||
db.session.close()
|
db.session.close()
|
||||||
return jsonify(json_data)
|
return jsonify(json_data)
|
||||||
|
@ -222,7 +235,6 @@ def admin_keys(chalid):
|
||||||
|
|
||||||
newkeys = request.form.getlist('keys[]')
|
newkeys = request.form.getlist('keys[]')
|
||||||
newvals = request.form.getlist('vals[]')
|
newvals = request.form.getlist('vals[]')
|
||||||
print(list(zip(newkeys, newvals)))
|
|
||||||
flags = []
|
flags = []
|
||||||
for flag, val in zip(newkeys, newvals):
|
for flag, val in zip(newkeys, newvals):
|
||||||
flag_dict = {'flag':flag, 'type':int(val)}
|
flag_dict = {'flag':flag, 'type':int(val)}
|
||||||
|
@ -319,7 +331,6 @@ def admin_teams(page):
|
||||||
|
|
||||||
teams = Teams.query.slice(page_start, page_end).all()
|
teams = Teams.query.slice(page_start, page_end).all()
|
||||||
count = db.session.query(db.func.count(Teams.id)).first()[0]
|
count = db.session.query(db.func.count(Teams.id)).first()[0]
|
||||||
print(count)
|
|
||||||
pages = int(count / results_per_page) + (count % results_per_page > 0)
|
pages = int(count / results_per_page) + (count % results_per_page > 0)
|
||||||
return render_template('admin/teams.html', teams=teams, pages=pages)
|
return render_template('admin/teams.html', teams=teams, pages=pages)
|
||||||
|
|
||||||
|
@ -331,11 +342,14 @@ def admin_team(teamid):
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
solves = Solves.query.filter_by(teamid=teamid).all()
|
solves = Solves.query.filter_by(teamid=teamid).all()
|
||||||
|
solve_ids = [s.chalid for s in solves]
|
||||||
|
missing = Challenges.query.filter( not_(Challenges.id.in_(solve_ids) ) ).all()
|
||||||
addrs = Tracking.query.filter_by(team=teamid).order_by(Tracking.date.desc()).group_by(Tracking.ip).all()
|
addrs = Tracking.query.filter_by(team=teamid).order_by(Tracking.date.desc()).group_by(Tracking.ip).all()
|
||||||
wrong_keys = WrongKeys.query.filter_by(team=teamid).order_by(WrongKeys.date.desc()).all()
|
wrong_keys = WrongKeys.query.filter_by(team=teamid).order_by(WrongKeys.date.desc()).all()
|
||||||
score = user.score()
|
score = user.score()
|
||||||
place = user.place()
|
place = user.place()
|
||||||
return render_template('admin/team.html', solves=solves, team=user, addrs=addrs, score=score, place=place, wrong_keys=wrong_keys)
|
return render_template('admin/team.html', solves=solves, team=user, addrs=addrs, score=score, missing=missing,
|
||||||
|
place=place, wrong_keys=wrong_keys)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
admin_user = request.form.get('admin', None)
|
admin_user = request.form.get('admin', None)
|
||||||
if admin_user:
|
if admin_user:
|
||||||
|
|
|
@ -90,14 +90,19 @@ table{
|
||||||
border: None;
|
border: None;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chal-button > p {
|
.chal-button > .chal-name {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chal-button > span{
|
.chal-button > .chal-points {
|
||||||
font-size: 14px;
|
margin-bottom: 0px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chal-button > .chal-percent{
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remove-key{
|
.remove-key{
|
||||||
|
|
|
@ -167,7 +167,7 @@ function loadchals(){
|
||||||
|
|
||||||
for (var i = 0; i <= challenges['game'].length - 1; i++) {
|
for (var i = 0; i <= challenges['game'].length - 1; i++) {
|
||||||
var chal = challenges['game'][i]
|
var chal = challenges['game'][i]
|
||||||
var chal_button = $('<button class="chal-button col-md-2 theme-background" value="{0}"><p>{1}</p><span>{2}</span></button>'.format(chal.id, chal.name, chal.value))
|
var chal_button = $('<button class="chal-button col-md-2 theme-background" value="{0}"><p class="chal-name">{1}</p><p class="chal-points">{2}</p><span class="chal-percent">{3}% solved</span></button>'.format(chal.id, chal.name, chal.value, Math.round(chal.percentage_solved * 100)));
|
||||||
$('#' + challenges['game'][i].category.replace(/ /g,"-").hashCode()).append(chal_button);
|
$('#' + challenges['game'][i].category.replace(/ /g,"-").hashCode()).append(chal_button);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,8 +179,8 @@ function loadchals(){
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.create-challenge').click(function (e) {
|
$('.create-challenge').click(function (e) {
|
||||||
$('#new-chal-category').val($($(this).siblings()[0]).text().trim())
|
$('#new-chal-category').val($($(this).siblings()[0]).text().trim());
|
||||||
$('#new-chal-title').text($($(this).siblings()[0]).text().trim())
|
$('#new-chal-title').text($($(this).siblings()[0]).text().trim());
|
||||||
$('#new-challenge').modal();
|
$('#new-challenge').modal();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<br>
|
<h1>Scoreboard</h1>
|
||||||
<table id="scoreboard" class="table table-striped">
|
<table id="scoreboard" class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -101,6 +101,28 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<h3>Missing</h3>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center"><b>Challenge</b></td>
|
||||||
|
<td class="text-center"><b>Category</b></td>
|
||||||
|
<td class="text-center"><b>Value</b></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for chal in missing %}
|
||||||
|
<tr class="chal-solve">
|
||||||
|
<td class="text-center chal" id="{{ chal.chalid }}">{{ chal.name }}</td>
|
||||||
|
<td class="text-center">{{ chal.category }}</td>
|
||||||
|
<td class="text-center">{{ chal.value }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<h3>Wrong Keys</h3>
|
<h3>Wrong Keys</h3>
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -11,7 +11,7 @@ input[type="checkbox"] { margin: 0px !important; position: relative; top: 5px; }
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<br>
|
<h1>Teams</h1>
|
||||||
<div id="confirm" class="modal fade" tabindex="-1">
|
<div id="confirm" class="modal fade" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
|
@ -29,8 +29,6 @@ def tracker():
|
||||||
@views.before_request
|
@views.before_request
|
||||||
def csrf():
|
def csrf():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
print(session)
|
|
||||||
print(request.form.get('nonce'))
|
|
||||||
if session['nonce'] != request.form.get('nonce'):
|
if session['nonce'] != request.form.get('nonce'):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
@ -99,7 +97,6 @@ def setup():
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
app.setup = False
|
app.setup = False
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
print(session.get('nonce'))
|
|
||||||
return render_template('setup.html', nonce=session.get('nonce'))
|
return render_template('setup.html', nonce=session.get('nonce'))
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
|
@ -134,10 +131,10 @@ def teams(page):
|
||||||
|
|
||||||
teams = Teams.query.slice(page_start, page_end).all()
|
teams = Teams.query.slice(page_start, page_end).all()
|
||||||
count = db.session.query(db.func.count(Teams.id)).first()[0]
|
count = db.session.query(db.func.count(Teams.id)).first()[0]
|
||||||
print(count)
|
|
||||||
pages = int(count / results_per_page) + (count % results_per_page > 0)
|
pages = int(count / results_per_page) + (count % results_per_page > 0)
|
||||||
return render_template('teams.html', teams=teams, team_pages=pages, curr_page=page)
|
return render_template('teams.html', teams=teams, team_pages=pages, curr_page=page)
|
||||||
|
|
||||||
|
|
||||||
@views.route('/team/<teamid>', methods=['GET', 'POST'])
|
@views.route('/team/<teamid>', methods=['GET', 'POST'])
|
||||||
def team(teamid):
|
def team(teamid):
|
||||||
user = Teams.query.filter_by(id=teamid).first()
|
user = Teams.query.filter_by(id=teamid).first()
|
||||||
|
|
Loading…
Reference in New Issue