mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-18 06:24:23 +01:00
Merge pull request #42 from slinkymanbyday/view_keys_interface
view incorrect/correct key submission interfaces
This commit is contained in:
@@ -452,6 +452,15 @@ def init_admin(app):
|
|||||||
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({'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)})
|
||||||
return jsonify(json)
|
return jsonify(json)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/admin/solves/<teamid>/<chalid>/delete', methods=['POST'])
|
||||||
|
@admins_only
|
||||||
|
def delete_solve(teamid, chalid):
|
||||||
|
solve = Solves.query.filter_by(teamid=teamid, chalid=chalid).first()
|
||||||
|
db.session.delete(solve)
|
||||||
|
db.session.commit()
|
||||||
|
return '1'
|
||||||
|
|
||||||
@app.route('/admin/statistics', methods=['GET'])
|
@app.route('/admin/statistics', methods=['GET'])
|
||||||
@admins_only
|
@admins_only
|
||||||
def admin_stats():
|
def admin_stats():
|
||||||
@@ -474,7 +483,39 @@ def init_admin(app):
|
|||||||
least_solved=least_solved_chal
|
least_solved=least_solved_chal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@app.route('/admin/wrong_keys/<page>', methods=['GET'])
|
||||||
|
@admins_only
|
||||||
|
def admin_wrong_key(page='1'):
|
||||||
|
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
|
||||||
|
|
||||||
|
wrong_keys = WrongKeys.query.add_columns(WrongKeys.flag, WrongKeys.team, WrongKeys.date,\
|
||||||
|
Challenges.name.label('chal_name'), Teams.name.label('team_name')).\
|
||||||
|
join(Challenges).join(Teams).order_by('team_name ASC').slice(page_start, page_end).all()
|
||||||
|
|
||||||
|
wrong_count = db.session.query(db.func.count(WrongKeys.id)).first()[0]
|
||||||
|
pages = int(wrong_count / results_per_page) + (wrong_count % results_per_page > 0)
|
||||||
|
|
||||||
|
return render_template('admin/wrong_keys.html', wrong_keys=wrong_keys, pages=pages)
|
||||||
|
|
||||||
|
@app.route('/admin/correct_keys/<page>', methods=['GET'])
|
||||||
|
@admins_only
|
||||||
|
def admin_correct_key(page='1'):
|
||||||
|
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
|
||||||
|
|
||||||
|
solves = Solves.query.add_columns(Solves.chalid, Solves.teamid, Solves.date, Solves.flag, \
|
||||||
|
Challenges.name.label('chal_name'), Teams.name.label('team_name')).\
|
||||||
|
join(Challenges).join(Teams).order_by('team_name ASC').slice(page_start, page_end).all()
|
||||||
|
|
||||||
|
solve_count = db.session.query(db.func.count(Solves.id)).first()[0]
|
||||||
|
pages = int(solve_count / results_per_page) + (solve_count % results_per_page > 0)
|
||||||
|
|
||||||
|
return render_template('admin/correct_keys.html', solves=solves, pages=pages)
|
||||||
|
|
||||||
@app.route('/admin/fails/<teamid>', methods=['GET'])
|
@app.route('/admin/fails/<teamid>', methods=['GET'])
|
||||||
@admins_only
|
@admins_only
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ def init_challenges(app):
|
|||||||
for x in keys:
|
for x in keys:
|
||||||
if x.key_type == 0: #static key
|
if x.key_type == 0: #static key
|
||||||
if x.flag.strip().lower() == key:
|
if x.flag.strip().lower() == key:
|
||||||
solve = Solves(chalid=chalid, teamid=session['id'], ip=request.remote_addr)
|
solve = Solves(chalid=chalid, teamid=session['id'], ip=request.remote_addr, flag=key)
|
||||||
db.session.add(solve)
|
db.session.add(solve)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
db.session.close()
|
db.session.close()
|
||||||
@@ -129,7 +129,7 @@ def init_challenges(app):
|
|||||||
elif x.key_type == 1: #regex
|
elif x.key_type == 1: #regex
|
||||||
res = re.match(str(x), key, re.IGNORECASE)
|
res = re.match(str(x), key, re.IGNORECASE)
|
||||||
if res and res.group() == key:
|
if res and res.group() == key:
|
||||||
solve = Solves(chalid=chalid, teamid=session['id'], ip=request.remote_addr)
|
solve = Solves(chalid=chalid, teamid=session['id'], ip=request.remote_addr, flag=key)
|
||||||
db.session.add(solve)
|
db.session.add(solve)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
db.session.close()
|
db.session.close()
|
||||||
|
|||||||
@@ -135,15 +135,17 @@ class Solves(db.Model):
|
|||||||
chalid = db.Column(db.Integer, db.ForeignKey('challenges.id'))
|
chalid = db.Column(db.Integer, db.ForeignKey('challenges.id'))
|
||||||
teamid = db.Column(db.Integer, db.ForeignKey('teams.id'))
|
teamid = db.Column(db.Integer, db.ForeignKey('teams.id'))
|
||||||
ip = db.Column(db.Integer)
|
ip = db.Column(db.Integer)
|
||||||
|
flag = db.Column(db.Text)
|
||||||
date = db.Column(db.DateTime, default=datetime.datetime.utcnow)
|
date = db.Column(db.DateTime, default=datetime.datetime.utcnow)
|
||||||
team = db.relationship('Teams', foreign_keys="Solves.teamid", lazy='joined')
|
team = db.relationship('Teams', foreign_keys="Solves.teamid", lazy='joined')
|
||||||
chal = db.relationship('Challenges', foreign_keys="Solves.chalid", lazy='joined')
|
chal = db.relationship('Challenges', foreign_keys="Solves.chalid", lazy='joined')
|
||||||
# value = db.Column(db.Integer)
|
# value = db.Column(db.Integer)
|
||||||
|
|
||||||
def __init__(self, chalid, teamid, ip):
|
def __init__(self, chalid, teamid, ip, flag):
|
||||||
self.ip = ip2long(ip)
|
self.ip = ip2long(ip)
|
||||||
self.chalid = chalid
|
self.chalid = chalid
|
||||||
self.teamid = teamid
|
self.teamid = teamid
|
||||||
|
self.flag = flag
|
||||||
# self.value = value
|
# self.value = value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
89
templates/admin/correct_keys.html
Normal file
89
templates/admin/correct_keys.html
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{% extends "admin/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h1>Correct Key Submissions</h1>
|
||||||
|
<div id="confirm" class="reveal-modal" data-reveal>
|
||||||
|
<h2 class="text-center">Delete Key</h2>
|
||||||
|
<form method="POST">
|
||||||
|
<input id="nonce" type="hidden" name="nonce" value="{{ nonce }}">
|
||||||
|
<div class="small-6 small-centered text-center columns">
|
||||||
|
<p>Are you sure you want to delete successful key submission for team: <strong id="confirm-team-name"></strong> in challenge: <strong id="confirm-chal-name"></strong>?</p>
|
||||||
|
<button type="button" class="button alert radius" onclick="$('#confirm').foundation('reveal', 'close');">No</button>
|
||||||
|
<button type="button" id="delete-solve" class="button success radius">Yes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<a class="close-reveal-modal">×</a>
|
||||||
|
</div>
|
||||||
|
<table id="teamsboard">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center"><b>Team</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Challenge</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Date</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Key Submitted</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Delete</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for solve in solves %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center team" id="{{ solve.teamid }}"><a href="/admin/team/{{ solve.teamid }}">{{ solve.team_name }}</a>
|
||||||
|
<td class="text-center chal" id="{{ solve.chalid }}">{{ solve.chal_name }}</td>
|
||||||
|
<td class="text-center">{{ solve.date }}</td>
|
||||||
|
<td class="text-center">{{ solve.flag }}</td>
|
||||||
|
<td class="text-center"><i class="fa fa-times"></i></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% if pages > 1 %}
|
||||||
|
<div class="text-center">Page
|
||||||
|
<br>
|
||||||
|
{% for page in range(1, pages + 1) %}
|
||||||
|
<a href="{{ page }}">{{ page }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script>
|
||||||
|
$('#delete-solve').click(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
var solve = $('#confirm input[name="solve"]').val()
|
||||||
|
$.post($('#confirm form').attr('action'), $('#confirm form').serialize(), function(data){
|
||||||
|
var data = $.parseJSON(JSON.stringify(data))
|
||||||
|
if (data == "1"){
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
function load_confirm_modal(team, chal, team_name, chal_name){
|
||||||
|
var modal = $('#confirm')
|
||||||
|
modal.find('#confirm-team-name').text(team_name)
|
||||||
|
modal.find('#confirm-chal-name').text(chal_name)
|
||||||
|
$('#confirm form').attr('action', '/admin/solves/'+team+'/'+chal+'/delete');
|
||||||
|
$('#confirm').foundation('reveal', 'open');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.fa-times').click(function(){
|
||||||
|
var elem = $(this).parent().parent();
|
||||||
|
var chal = elem.find('.chal').attr('id');
|
||||||
|
var chal_name = elem.find('.chal').text().trim();
|
||||||
|
var team = elem.find('.team').attr('id');
|
||||||
|
var team_name = elem.find('.team').text().trim();
|
||||||
|
load_confirm_modal(team, chal, team_name, chal_name)
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
<h1>Statistics</h1>
|
<h1>Statistics</h1>
|
||||||
|
|
||||||
<h3><b>{{ team_count }}</b> teams registered</h3>
|
<h3><b>{{ team_count }}</b> teams registered</h3>
|
||||||
<h3><b>{{ wrong_count }}</b> wrong keys submitted</h3>
|
<h3><b>{{ wrong_count }}</b> <a href="wrong_keys/1">wrong keys</a> submitted</h3>
|
||||||
<h3><b>{{ solve_count }}</b> right keys submitted</h3>
|
<h3><b>{{ solve_count }}</b> <a href="correct_keys/1">right keys</a> submitted</h3>
|
||||||
<h3><b>{{ challenge_count }}</b> challenges</h3>
|
<h3><b>{{ challenge_count }}</b> challenges</h3>
|
||||||
{% if most_solved %}
|
{% if most_solved %}
|
||||||
<h3>Most solved: <b>{{ most_solved[0].chal.name }}</b> with {{ most_solved[1] }}</b> solves</h3>
|
<h3>Most solved: <b>{{ most_solved[0].chal.name }}</b> with {{ most_solved[1] }}</b> solves</h3>
|
||||||
|
|||||||
45
templates/admin/wrong_keys.html
Normal file
45
templates/admin/wrong_keys.html
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{% extends "admin/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h1>Incorrect Key Submissions</h1>
|
||||||
|
<table id="teamsboard">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center"><b>Team</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Challenge</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Date</b>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><b>Submitted Key</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for wrong_key in wrong_keys %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center"><a href="/admin/team/{{ wrong_key.team }}">{{ wrong_key.team_name }}</a>
|
||||||
|
<td class="text-center">{{ wrong_key.chal_name }}</td>
|
||||||
|
<td class="text-center">{{ wrong_key.date }}</td>
|
||||||
|
<td class="text-center">{{ wrong_key.flag }}</td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% if pages > 1 %}
|
||||||
|
<div class="text-center">Page
|
||||||
|
<br>
|
||||||
|
{% for page in range(1, pages + 1) %}
|
||||||
|
<a href="{{ page }}">{{ page }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user