mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 05:54:19 +01:00
Top ten endpoint honors users with the same name (#379)
* Make the /top/10 endpoint honor users with the same name
This commit is contained in:
@@ -87,7 +87,7 @@ def scores():
|
||||
|
||||
@scoreboard.route('/top/<int:count>')
|
||||
def topteams(count):
|
||||
json = {'scores': {}}
|
||||
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():
|
||||
@@ -98,7 +98,7 @@ def topteams(count):
|
||||
|
||||
standings = get_standings(count=count)
|
||||
|
||||
for team in standings:
|
||||
for i, team in enumerate(standings):
|
||||
solves = Solves.query.filter_by(teamid=team.teamid)
|
||||
awards = Awards.query.filter_by(teamid=team.teamid)
|
||||
|
||||
@@ -111,20 +111,24 @@ def topteams(count):
|
||||
solves = solves.all()
|
||||
awards = awards.all()
|
||||
|
||||
json['scores'][team.name] = []
|
||||
json['places'][i + 1] = {
|
||||
'id': team.teamid,
|
||||
'name': team.name,
|
||||
'solves': []
|
||||
}
|
||||
for x in solves:
|
||||
json['scores'][team.name].append({
|
||||
json['places'][i + 1]['solves'].append({
|
||||
'chal': x.chalid,
|
||||
'team': x.teamid,
|
||||
'value': x.chal.value,
|
||||
'time': utils.unix_time(x.date)
|
||||
})
|
||||
for award in awards:
|
||||
json['scores'][team.name].append({
|
||||
json['places'][i + 1]['solves'].append({
|
||||
'chal': None,
|
||||
'team': award.teamid,
|
||||
'value': award.value,
|
||||
'time': utils.unix_time(award.date)
|
||||
})
|
||||
json['scores'][team.name] = sorted(json['scores'][team.name], key=lambda k: k['time'])
|
||||
json['places'][i + 1]['solves'] = sorted(json['places'][i + 1]['solves'], key=lambda k: k['time'])
|
||||
return jsonify(json)
|
||||
|
||||
@@ -24,20 +24,20 @@ function UTCtoDate(utc){
|
||||
}
|
||||
function scoregraph () {
|
||||
$.get(script_root + '/top/10', function( data ) {
|
||||
var scores = $.parseJSON(JSON.stringify(data));
|
||||
scores = scores['scores'];
|
||||
if (Object.keys(scores).length == 0 ){
|
||||
var places = $.parseJSON(JSON.stringify(data));
|
||||
places = places['places'];
|
||||
if (Object.keys(places).length == 0 ){
|
||||
return;
|
||||
}
|
||||
|
||||
var teams = Object.keys(scores);
|
||||
var teams = Object.keys(places);
|
||||
var traces = [];
|
||||
for(var i = 0; i < teams.length; i++){
|
||||
var team_score = [];
|
||||
var times = [];
|
||||
for(var j = 0; j < scores[teams[i]].length; j++){
|
||||
team_score.push(scores[teams[i]][j].value);
|
||||
var date = moment(scores[teams[i]][j].time * 1000);
|
||||
for(var j = 0; j < places[teams[i]]['solves'].length; j++){
|
||||
team_score.push(places[teams[i]]['solves'][j].value);
|
||||
var date = moment(places[teams[i]]['solves'][j].time * 1000);
|
||||
times.push(date.toDate());
|
||||
}
|
||||
team_score = cumulativesum(team_score);
|
||||
@@ -45,7 +45,7 @@ function scoregraph () {
|
||||
x: times,
|
||||
y: team_score,
|
||||
mode: 'lines+markers',
|
||||
name: teams[i]
|
||||
name: places[teams[i]]['name']
|
||||
}
|
||||
traces.push(trace);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ from CTFd import create_app
|
||||
from CTFd.models import *
|
||||
from sqlalchemy_utils import database_exists, create_database, drop_database
|
||||
from sqlalchemy.engine.url import make_url
|
||||
import datetime
|
||||
|
||||
|
||||
def create_ctfd(ctf_name="CTFd", name="admin", email="admin@ctfd.io", password="password", setup=True):
|
||||
@@ -110,6 +111,7 @@ def gen_hint(db, chal, hint="This is a hint", cost=0, type=0):
|
||||
|
||||
def gen_solve(db, teamid, chalid, ip='127.0.0.1', flag='rightkey'):
|
||||
solve = Solves(teamid, chalid, ip, flag)
|
||||
solve.date = datetime.datetime.utcnow()
|
||||
db.session.add(solve)
|
||||
db.session.commit()
|
||||
return solve
|
||||
@@ -117,6 +119,7 @@ def gen_solve(db, teamid, chalid, ip='127.0.0.1', flag='rightkey'):
|
||||
|
||||
def gen_wrongkey(db, teamid, chalid, ip='127.0.0.1', flag='wrongkey'):
|
||||
wrongkey = WrongKeys(teamid, chalid, ip, flag)
|
||||
wrongkey.date = datetime.datetime.utcnow()
|
||||
db.session.add(wrongkey)
|
||||
db.session.commit()
|
||||
return wrongkey
|
||||
|
||||
80
tests/user/test_scoreboard.py
Normal file
80
tests/user/test_scoreboard.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from CTFd.models import Teams, Solves, WrongKeys
|
||||
from CTFd.utils import get_config, set_config
|
||||
from CTFd import utils
|
||||
from tests.helpers import *
|
||||
from freezegun import freeze_time
|
||||
from mock import patch
|
||||
import json
|
||||
|
||||
|
||||
def test_top_10():
|
||||
'''Make sure top10 returns correct information'''
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app, name="user1", email="user1@ctfd.io")
|
||||
register_user(app, name="user2", email="user2@ctfd.io")
|
||||
|
||||
chal1 = gen_challenge(app.db)
|
||||
flag1 = gen_flag(app.db, chal=chal1.id, flag='flag')
|
||||
chal1_id = chal1.id
|
||||
|
||||
chal2 = gen_challenge(app.db)
|
||||
flag2 = gen_flag(app.db, chal=chal2.id, flag='flag')
|
||||
chal2_id = chal2.id
|
||||
|
||||
# Generates solve for user1
|
||||
with freeze_time("2017-10-3 03:21:34"):
|
||||
gen_solve(app.db, teamid=2, chalid=chal1_id)
|
||||
|
||||
with freeze_time("2017-10-4 03:25:45"):
|
||||
gen_solve(app.db, teamid=2, chalid=chal2_id)
|
||||
|
||||
# Generate solve for user2
|
||||
with freeze_time("2017-10-3 03:21:34"):
|
||||
gen_solve(app.db, teamid=3, chalid=chal1_id)
|
||||
|
||||
client = login_as_user(app)
|
||||
r = client.get('/top/10')
|
||||
response = r.get_data(as_text=True)
|
||||
|
||||
saved = '''{
|
||||
"places": {
|
||||
"1": {
|
||||
"id": 2,
|
||||
"name": "user1",
|
||||
"solves": [
|
||||
{
|
||||
"chal": 1,
|
||||
"team": 2,
|
||||
"time": 1507000894,
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"chal": 2,
|
||||
"team": 2,
|
||||
"time": 1507087545,
|
||||
"value": 100
|
||||
}
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"id": 3,
|
||||
"name": "user2",
|
||||
"solves": [
|
||||
{
|
||||
"chal": 1,
|
||||
"team": 3,
|
||||
"time": 1507000894,
|
||||
"value": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}'''
|
||||
saved = json.loads(saved)
|
||||
received = json.loads(response)
|
||||
assert saved == received
|
||||
destroy_ctfd(app)
|
||||
Reference in New Issue
Block a user