mirror of https://github.com/JohnHammond/CTFd.git
Allow CTFd to run with script_root != '/' and PostgreSQL (#125)
Also, Add WSGI config exampleselenium-screenshot-testing
parent
a9b79770f8
commit
6b2257236f
|
@ -4,6 +4,7 @@ from CTFd.models import db, Teams, Solves, Awards, Containers, Challenges, Wrong
|
|||
from itsdangerous import TimedSerializer, BadTimeSignature
|
||||
from sqlalchemy.sql import and_, or_, not_
|
||||
from sqlalchemy.sql.expression import union_all
|
||||
from sqlalchemy.sql.functions import coalesce
|
||||
from werkzeug.utils import secure_filename
|
||||
from socket import inet_aton, inet_ntoa
|
||||
from passlib.hash import bcrypt_sha256
|
||||
|
@ -18,6 +19,8 @@ import json
|
|||
import datetime
|
||||
import calendar
|
||||
|
||||
from scoreboard import get_standings
|
||||
|
||||
admin = Blueprint('admin', __name__)
|
||||
|
||||
|
||||
|
@ -276,12 +279,12 @@ def delete_container(container_id):
|
|||
def new_container():
|
||||
name = request.form.get('name')
|
||||
if set(name) <= set('abcdefghijklmnopqrstuvwxyz0123456789-_'):
|
||||
return redirect('/admin/containers')
|
||||
return redirect(url_for('admin.list_container'))
|
||||
buildfile = request.form.get('buildfile')
|
||||
files = request.files.getlist('files[]')
|
||||
create_image(name=name, buildfile=buildfile, files=files)
|
||||
run_image(name)
|
||||
return redirect('/admin/containers')
|
||||
return redirect(url_for('admin.list_container'))
|
||||
|
||||
|
||||
|
||||
|
@ -291,7 +294,7 @@ def admin_chals():
|
|||
if request.method == 'POST':
|
||||
chals = Challenges.query.add_columns('id', 'name', 'value', 'description', 'category', 'hidden').order_by(Challenges.value).all()
|
||||
|
||||
teams_with_points = db.session.query(Solves.teamid, Teams.name).join(Teams).filter(
|
||||
teams_with_points = db.session.query(Solves.teamid).join(Teams).filter(
|
||||
Teams.banned == False).group_by(
|
||||
Solves.teamid).count()
|
||||
|
||||
|
@ -427,7 +430,7 @@ def admin_teams(page):
|
|||
page_start = results_per_page * ( page - 1 )
|
||||
page_end = results_per_page * ( page - 1 ) + results_per_page
|
||||
|
||||
teams = Teams.query.slice(page_start, page_end).all()
|
||||
teams = Teams.query.order_by(Teams.id.asc()).slice(page_start, page_end).all()
|
||||
count = db.session.query(db.func.count(Teams.id)).first()[0]
|
||||
pages = int(count / results_per_page) + (count % results_per_page > 0)
|
||||
return render_template('admin/teams.html', teams=teams, pages=pages, curr_page=page)
|
||||
|
@ -442,7 +445,9 @@ def admin_team(teamid):
|
|||
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 = db.session.query(Tracking.ip, db.func.max(Tracking.date)) \
|
||||
.filter_by(team=teamid) \
|
||||
.group_by(Tracking.ip).all()
|
||||
wrong_keys = WrongKeys.query.filter_by(teamid=teamid).order_by(WrongKeys.date.asc()).all()
|
||||
awards = Awards.query.filter_by(teamid=teamid).order_by(Awards.date.asc()).all()
|
||||
score = user.score()
|
||||
|
@ -452,10 +457,12 @@ def admin_team(teamid):
|
|||
elif request.method == 'POST':
|
||||
admin_user = request.form.get('admin', None)
|
||||
if admin_user:
|
||||
admin_user = 1 if admin_user == "true" else 0
|
||||
admin_user = True if admin_user == 'true' else False
|
||||
user.admin = admin_user
|
||||
# Set user.banned to hide admins from scoreboard
|
||||
user.banned = admin_user
|
||||
db.session.commit()
|
||||
db.session.close()
|
||||
return jsonify({'data': ['success']})
|
||||
|
||||
name = request.form.get('name', None)
|
||||
|
@ -545,35 +552,21 @@ def admin_graph(graph_type):
|
|||
json_data['categories'].append({'category':category, 'count':count})
|
||||
return jsonify(json_data)
|
||||
elif graph_type == "solves":
|
||||
solves = Solves.query.join(Teams).filter(Teams.banned == False).add_columns(db.func.count(Solves.chalid)).group_by(Solves.chalid).all()
|
||||
solves_sub = db.session.query(Solves.chalid, db.func.count(Solves.chalid).label('solves_cnt')) \
|
||||
.join(Teams, Solves.teamid == Teams.id).filter(Teams.banned == False) \
|
||||
.group_by(Solves.chalid).subquery()
|
||||
solves = db.session.query(solves_sub.columns.chalid, solves_sub.columns.solves_cnt, Challenges.name) \
|
||||
.join(Challenges, solves_sub.columns.chalid == Challenges.id).all()
|
||||
json_data = {}
|
||||
for chal, count in solves:
|
||||
json_data[chal.chal.name] = count
|
||||
for chal, count, name in solves:
|
||||
json_data[name] = count
|
||||
return jsonify(json_data)
|
||||
|
||||
|
||||
@admin.route('/admin/scoreboard')
|
||||
@admins_only
|
||||
def admin_scoreboard():
|
||||
score = db.func.sum(Challenges.value).label('score')
|
||||
scores = db.session.query(Solves.teamid.label('teamid'), Teams.name.label('name'), Teams.banned.label('banned'), score, Solves.date.label('date')) \
|
||||
.join(Teams) \
|
||||
.join(Challenges) \
|
||||
.group_by(Solves.teamid)
|
||||
|
||||
awards = db.session.query(Teams.id.label('teamid'), Teams.name.label('name'), Teams.banned.label('banned'),
|
||||
db.func.sum(Awards.value).label('score'), Awards.date.label('date')) \
|
||||
.filter(Teams.id == Awards.teamid) \
|
||||
.group_by(Teams.id)
|
||||
|
||||
results = union_all(scores, awards).alias('results')
|
||||
|
||||
standings = db.session.query(results.columns.teamid, results.columns.name, results.columns.banned,
|
||||
db.func.sum(results.columns.score).label('score')) \
|
||||
.group_by(results.columns.teamid) \
|
||||
.order_by(db.func.sum(results.columns.score).desc(), db.func.max(results.columns.date)) \
|
||||
.all()
|
||||
db.session.close()
|
||||
standings = get_standings(admin=True)
|
||||
return render_template('admin/scoreboard.html', teams=standings)
|
||||
|
||||
|
||||
|
@ -711,9 +704,18 @@ def admin_stats():
|
|||
wrong_count = db.session.query(db.func.count(WrongKeys.id)).first()[0]
|
||||
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 = Challenges.query.add_columns(db.func.count(Solves.chalid).label('solves')).outerjoin(Solves).group_by(Challenges.id).order_by('solves ASC').first()
|
||||
|
||||
|
||||
solves_raw = db.func.count(Solves.chalid).label('solves_raw')
|
||||
solves_sub = db.session.query(Solves.chalid, solves_raw) \
|
||||
.group_by(Solves.chalid).subquery()
|
||||
solves_cnt = coalesce(solves_sub.columns.solves_raw, 0).label('solves_cnt')
|
||||
most_solved_chal = Challenges.query.add_columns(solves_cnt) \
|
||||
.outerjoin(solves_sub, solves_sub.columns.chalid == Challenges.id) \
|
||||
.order_by(solves_cnt.desc()).first()
|
||||
least_solved_chal = Challenges.query.add_columns(solves_cnt) \
|
||||
.outerjoin(solves_sub, solves_sub.columns.chalid == Challenges.id) \
|
||||
.order_by(solves_cnt.asc()).first()
|
||||
|
||||
db.session.close()
|
||||
|
||||
return render_template('admin/statistics.html', team_count=teams_registered,
|
||||
|
|
|
@ -172,4 +172,4 @@ def login():
|
|||
def logout():
|
||||
if authed():
|
||||
session.clear()
|
||||
return redirect('/')
|
||||
return redirect(url_for('views.static_html'))
|
||||
|
|
|
@ -20,7 +20,7 @@ def challenges_view():
|
|||
if view_after_ctf():
|
||||
pass
|
||||
else:
|
||||
return redirect('/')
|
||||
return redirect(url_for('views.static_html'))
|
||||
if get_config('verify_emails') and not is_verified():
|
||||
return redirect(url_for('auth.confirm_user'))
|
||||
if can_view_challenges():
|
||||
|
@ -36,7 +36,7 @@ def chals():
|
|||
if view_after_ctf():
|
||||
pass
|
||||
else:
|
||||
return redirect('/')
|
||||
return redirect(url_for('views.static_html'))
|
||||
if can_view_challenges():
|
||||
chals = Challenges.query.filter(or_(Challenges.hidden != True, Challenges.hidden == None)).add_columns('id', 'name', 'value', 'description', 'category').order_by(Challenges.value).all()
|
||||
|
||||
|
@ -56,10 +56,13 @@ def chals():
|
|||
@challenges.route('/chals/solves')
|
||||
def chals_per_solves():
|
||||
if can_view_challenges():
|
||||
solves = Solves.query.join(Teams, Solves.teamid == Teams.id).filter(Teams.banned == False).add_columns(db.func.count(Solves.chalid)).group_by(Solves.chalid).all()
|
||||
solves_sub = db.session.query(Solves.chalid, db.func.count(Solves.chalid).label('solves')).join(Teams, Solves.teamid == Teams.id).filter(Teams.banned == False).group_by(Solves.chalid).subquery()
|
||||
solves = db.session.query(solves_sub.columns.chalid, solves_sub.columns.solves, Challenges.name) \
|
||||
.join(Challenges, solves_sub.columns.chalid == Challenges.id).all()
|
||||
json = {}
|
||||
for chal, count in solves:
|
||||
json[chal.chal.name] = count
|
||||
for chal, count, name in solves:
|
||||
json[name] = count
|
||||
db.session.close()
|
||||
return jsonify(json)
|
||||
return redirect(url_for('auth.login', next='chals/solves'))
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ class Solves(db.Model):
|
|||
id = db.Column(db.Integer, primary_key=True)
|
||||
chalid = db.Column(db.Integer, db.ForeignKey('challenges.id'))
|
||||
teamid = db.Column(db.Integer, db.ForeignKey('teams.id'))
|
||||
ip = db.Column(db.Integer)
|
||||
ip = db.Column(db.BigInteger)
|
||||
flag = db.Column(db.Text)
|
||||
date = db.Column(db.DateTime, default=datetime.datetime.utcnow)
|
||||
team = db.relationship('Teams', foreign_keys="Solves.teamid", lazy='joined')
|
||||
|
|
|
@ -5,31 +5,37 @@ from sqlalchemy.sql.expression import union_all
|
|||
|
||||
scoreboard = Blueprint('scoreboard', __name__)
|
||||
|
||||
def get_standings(admin=False, count=None):
|
||||
score = db.func.sum(Challenges.value).label('score')
|
||||
date = db.func.max(Solves.date).label('date')
|
||||
scores = db.session.query(Solves.teamid.label('teamid'), score, date).join(Challenges).group_by(Solves.teamid)
|
||||
awards = db.session.query(Awards.teamid.label('teamid'), db.func.sum(Awards.value).label('score'), db.func.max(Awards.date).label('date')) \
|
||||
.group_by(Awards.teamid)
|
||||
results = union_all(scores, awards).alias('results')
|
||||
sumscores = db.session.query(results.columns.teamid, db.func.sum(results.columns.score).label('score'), db.func.max(results.columns.date).label('date')) \
|
||||
.group_by(results.columns.teamid).subquery()
|
||||
if admin:
|
||||
standings_query = db.session.query(Teams.id.label('teamid'), Teams.name.label('name'), Teams.banned, sumscores.columns.score) \
|
||||
.join(sumscores, Teams.id == sumscores.columns.teamid) \
|
||||
.order_by(sumscores.columns.score.desc(), sumscores.columns.date)
|
||||
else:
|
||||
standings_query = db.session.query(Teams.id.label('teamid'), Teams.name.label('name'), sumscores.columns.score) \
|
||||
.join(sumscores, Teams.id == sumscores.columns.teamid) \
|
||||
.filter(Teams.banned == False) \
|
||||
.order_by(sumscores.columns.score.desc(), sumscores.columns.date)
|
||||
if count is not None:
|
||||
standings = standings_query.all()
|
||||
else:
|
||||
standings = standings_query.limit(count).all()
|
||||
db.session.close()
|
||||
return standings
|
||||
|
||||
|
||||
@scoreboard.route('/scoreboard')
|
||||
def scoreboard_view():
|
||||
if get_config('view_scoreboard_if_authed') and not authed():
|
||||
return redirect(url_for('auth.login', next=request.path))
|
||||
score = db.func.sum(Challenges.value).label('score')
|
||||
scores = db.session.query(Solves.teamid.label('teamid'), Teams.name.label('name'), score, Solves.date.label('date')) \
|
||||
.join(Teams) \
|
||||
.join(Challenges) \
|
||||
.filter(Teams.banned == False) \
|
||||
.group_by(Solves.teamid)
|
||||
|
||||
awards = db.session.query(Teams.id.label('teamid'), Teams.name.label('name'),
|
||||
db.func.sum(Awards.value).label('score'), Awards.date.label('date')) \
|
||||
.filter(Teams.id == Awards.teamid) \
|
||||
.group_by(Teams.id)
|
||||
|
||||
results = union_all(scores, awards).alias('results')
|
||||
|
||||
standings = db.session.query(results.columns.teamid, results.columns.name,
|
||||
db.func.sum(results.columns.score).label('score')) \
|
||||
.group_by(results.columns.teamid) \
|
||||
.order_by(db.func.sum(results.columns.score).desc(), db.func.max(results.columns.date)) \
|
||||
.all()
|
||||
db.session.close()
|
||||
standings = get_standings()
|
||||
return render_template('scoreboard.html', teams=standings)
|
||||
|
||||
|
||||
|
@ -37,25 +43,7 @@ def scoreboard_view():
|
|||
def scores():
|
||||
if get_config('view_scoreboard_if_authed') and not authed():
|
||||
return redirect(url_for('auth.login', next=request.path))
|
||||
score = db.func.sum(Challenges.value).label('score')
|
||||
scores = db.session.query(Solves.teamid.label('teamid'), Teams.name.label('name'), score, Solves.date.label('date')) \
|
||||
.join(Teams) \
|
||||
.join(Challenges) \
|
||||
.filter(Teams.banned == False) \
|
||||
.group_by(Solves.teamid)
|
||||
|
||||
awards = db.session.query(Teams.id.label('teamid'), Teams.name.label('name'), db.func.sum(Awards.value).label('score'), Awards.date.label('date'))\
|
||||
.filter(Teams.id==Awards.teamid)\
|
||||
.group_by(Teams.id)
|
||||
|
||||
results = union_all(scores, awards).alias('results')
|
||||
|
||||
standings = db.session.query(results.columns.teamid, results.columns.name, db.func.sum(results.columns.score).label('score'))\
|
||||
.group_by(results.columns.teamid)\
|
||||
.order_by(db.func.sum(results.columns.score).desc(), db.func.max(results.columns.date))\
|
||||
.all()
|
||||
|
||||
db.session.close()
|
||||
standings = get_standings()
|
||||
json = {'standings':[]}
|
||||
for i, x in enumerate(standings):
|
||||
json['standings'].append({'pos':i+1, 'id':x.teamid, 'team':x.name,'score':int(x.score)})
|
||||
|
@ -74,26 +62,7 @@ def topteams(count):
|
|||
count = 10
|
||||
|
||||
json = {'scores':{}}
|
||||
|
||||
score = db.func.sum(Challenges.value).label('score')
|
||||
scores = db.session.query(Solves.teamid.label('teamid'), Teams.name.label('name'), score, Solves.date.label('date')) \
|
||||
.join(Teams) \
|
||||
.join(Challenges) \
|
||||
.filter(Teams.banned == False) \
|
||||
.group_by(Solves.teamid)
|
||||
|
||||
awards = db.session.query(Teams.id.label('teamid'), Teams.name.label('name'),
|
||||
db.func.sum(Awards.value).label('score'), Awards.date.label('date')) \
|
||||
.filter(Teams.id == Awards.teamid) \
|
||||
.group_by(Teams.id)
|
||||
|
||||
results = union_all(scores, awards).alias('results')
|
||||
|
||||
standings = db.session.query(results.columns.teamid, results.columns.name,
|
||||
db.func.sum(results.columns.score).label('score')) \
|
||||
.group_by(results.columns.teamid) \
|
||||
.order_by(db.func.sum(results.columns.score).desc(), db.func.max(results.columns.date)) \
|
||||
.limit(count).all()
|
||||
standings = get_standings(count=count)
|
||||
|
||||
for team in standings:
|
||||
solves = Solves.query.filter_by(teamid=team.teamid).all()
|
||||
|
|
|
@ -46,7 +46,7 @@ function loadchal(id, update) {
|
|||
}
|
||||
|
||||
function submitkey(chal, key) {
|
||||
$.post("/admin/chal/" + chal, {
|
||||
$.post(script_root + "/admin/chal/" + chal, {
|
||||
key: key,
|
||||
nonce: $('#nonce').val()
|
||||
}, function (data) {
|
||||
|
@ -55,7 +55,7 @@ function submitkey(chal, key) {
|
|||
}
|
||||
|
||||
function loadkeys(chal){
|
||||
$.get('/admin/keys/' + chal, function(data){
|
||||
$.get(script_root + '/admin/keys/' + chal, function(data){
|
||||
$('#keys-chal').val(chal);
|
||||
keys = $.parseJSON(JSON.stringify(data));
|
||||
keys = keys['keys'];
|
||||
|
@ -84,7 +84,7 @@ function updatekeys(){
|
|||
$('#current-keys input[name*="key_type"]:checked').each(function(){
|
||||
vals.push($(this).val());
|
||||
})
|
||||
$.post('/admin/keys/'+chal, {'keys':keys, 'vals':vals, 'nonce': $('#nonce').val()})
|
||||
$.post(script_root + '/admin/keys/'+chal, {'keys':keys, 'vals':vals, 'nonce': $('#nonce').val()})
|
||||
loadchal(chal, true)
|
||||
$('#update-keys').modal('hide');
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ function loadtags(chal){
|
|||
$('#tags-chal').val(chal)
|
||||
$('#current-tags').empty()
|
||||
$('#chal-tags').empty()
|
||||
$.get('/admin/tags/'+chal, function(data){
|
||||
$.get(script_root + '/admin/tags/'+chal, function(data){
|
||||
tags = $.parseJSON(JSON.stringify(data))
|
||||
tags = tags['tags']
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
|
@ -108,11 +108,11 @@ function loadtags(chal){
|
|||
}
|
||||
|
||||
function deletetag(tagid){
|
||||
$.post('/admin/tags/'+tagid+'/delete', {'nonce': $('#nonce').val()});
|
||||
$.post(script_root + '/admin/tags/'+tagid+'/delete', {'nonce': $('#nonce').val()});
|
||||
}
|
||||
|
||||
function deletechal(chalid){
|
||||
$.post('/admin/chal/delete', {'nonce':$('#nonce').val(), 'id':chalid});
|
||||
$.post(script_root + '/admin/chal/delete', {'nonce':$('#nonce').val(), 'id':chalid});
|
||||
}
|
||||
|
||||
function updatetags(){
|
||||
|
@ -121,13 +121,13 @@ function updatetags(){
|
|||
$('#chal-tags > span > span').each(function(i, e){
|
||||
tags.push($(e).text())
|
||||
});
|
||||
$.post('/admin/tags/'+chal, {'tags':tags, 'nonce': $('#nonce').val()})
|
||||
$.post(script_root + '/admin/tags/'+chal, {'tags':tags, 'nonce': $('#nonce').val()})
|
||||
loadchal(chal)
|
||||
}
|
||||
|
||||
function loadfiles(chal){
|
||||
$('#update-files form').attr('action', '/admin/files/'+chal)
|
||||
$.get('/admin/files/' + chal, function(data){
|
||||
$('#update-files form').attr('action', script_root+'/admin/files/'+chal)
|
||||
$.get(script_root + '/admin/files/' + chal, function(data){
|
||||
$('#files-chal').val(chal)
|
||||
files = $.parseJSON(JSON.stringify(data));
|
||||
files = files['files']
|
||||
|
@ -141,7 +141,7 @@ function loadfiles(chal){
|
|||
}
|
||||
|
||||
function deletefile(chal, file, elem){
|
||||
$.post('/admin/files/' + chal,{
|
||||
$.post(script_root + '/admin/files/' + chal,{
|
||||
'nonce': $('#nonce').val(),
|
||||
'method': 'delete',
|
||||
'file': file
|
||||
|
@ -155,7 +155,7 @@ function deletefile(chal, file, elem){
|
|||
|
||||
function loadchals(){
|
||||
$('#challenges').empty();
|
||||
$.post("/admin/chals", {
|
||||
$.post(script_root + "/admin/chals", {
|
||||
'nonce': $('#nonce').val()
|
||||
}, function (data) {
|
||||
categories = [];
|
||||
|
@ -207,7 +207,7 @@ $('#submit-tags').click(function (e) {
|
|||
|
||||
$('#delete-chal form').submit(function(e){
|
||||
e.preventDefault();
|
||||
$.post('/admin/chal/delete', $(this).serialize(), function(data){
|
||||
$.post(script_root + '/admin/chal/delete', $(this).serialize(), function(data){
|
||||
console.log(data)
|
||||
if (data){
|
||||
loadchals();
|
||||
|
|
|
@ -16,7 +16,7 @@ function scoregraph () {
|
|||
var times = []
|
||||
var scores = []
|
||||
var teamname = $('#team-id').text()
|
||||
$.get('/admin/solves/'+teamid(), function( data ) {
|
||||
$.get(script_root + '/admin/solves/'+teamid(), function( data ) {
|
||||
var solves = $.parseJSON(JSON.stringify(data));
|
||||
solves = solves['solves'];
|
||||
|
||||
|
@ -48,7 +48,7 @@ function scoregraph () {
|
|||
|
||||
function keys_percentage_graph(){
|
||||
// Solves and Fails pie chart
|
||||
$.get('/admin/fails/'+teamid(), function(data){
|
||||
$.get(script_root + '/admin/fails/'+teamid(), function(data){
|
||||
var res = $.parseJSON(JSON.stringify(data));
|
||||
var solves = res['solves'];
|
||||
var fails = res['fails'];
|
||||
|
@ -75,7 +75,7 @@ function keys_percentage_graph(){
|
|||
}
|
||||
|
||||
function category_breakdown_graph(){
|
||||
$.get('/admin/solves/'+teamid(), function(data){
|
||||
$.get(script_root + '/admin/solves/'+teamid(), function(data){
|
||||
var solves = $.parseJSON(JSON.stringify(data));
|
||||
solves = solves['solves'];
|
||||
|
||||
|
@ -126,4 +126,4 @@ window.onresize = function () {
|
|||
Plotly.Plots.resize(document.getElementById('keys-pie-graph'));
|
||||
Plotly.Plots.resize(document.getElementById('categories-pie-graph'));
|
||||
Plotly.Plots.resize(document.getElementById('score-graph'));
|
||||
};
|
||||
};
|
||||
|
|
|
@ -58,7 +58,7 @@ $("#answer-input").keyup(function(event){
|
|||
function submitkey(chal, key, nonce) {
|
||||
$('#submit-key').addClass("disabled-button");
|
||||
$('#submit-key').prop('disabled', true);
|
||||
$.post("/chal/" + chal, {
|
||||
$.post(script_root + "/chal/" + chal, {
|
||||
key: key,
|
||||
nonce: nonce
|
||||
}, function (data) {
|
||||
|
@ -103,7 +103,7 @@ function submitkey(chal, key, nonce) {
|
|||
}
|
||||
|
||||
function marksolves() {
|
||||
$.get('/solves', function (data) {
|
||||
$.get(script_root + '/solves', function (data) {
|
||||
solves = $.parseJSON(JSON.stringify(data));
|
||||
for (var i = solves['solves'].length - 1; i >= 0; i--) {
|
||||
id = solves['solves'][i].chalid;
|
||||
|
@ -118,7 +118,7 @@ function marksolves() {
|
|||
}
|
||||
|
||||
function updatesolves(){
|
||||
$.get('/chals/solves', function (data) {
|
||||
$.get(script_root + '/chals/solves', function (data) {
|
||||
solves = $.parseJSON(JSON.stringify(data));
|
||||
chals = Object.keys(solves);
|
||||
|
||||
|
@ -133,7 +133,7 @@ function updatesolves(){
|
|||
}
|
||||
|
||||
function getsolves(id){
|
||||
$.get('/chal/'+id+'/solves', function (data) {
|
||||
$.get(script_root + '/chal/'+id+'/solves', function (data) {
|
||||
var teams = data['teams'];
|
||||
var box = $('#chal-solves-names');
|
||||
box.empty();
|
||||
|
@ -147,8 +147,7 @@ function getsolves(id){
|
|||
}
|
||||
|
||||
function loadchals() {
|
||||
|
||||
$.get("/chals", function (data) {
|
||||
$.get(script_root + "/chals", function (data) {
|
||||
var categories = [];
|
||||
challenges = $.parseJSON(JSON.stringify(data));
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
function updatescores () {
|
||||
$.get('/scores', function( data ) {
|
||||
$.get(script_root + '/scores', function( data ) {
|
||||
teams = $.parseJSON(JSON.stringify(data));
|
||||
$('#scoreboard > tbody').empty()
|
||||
for (var i = 0; i < teams['standings'].length; i++) {
|
||||
|
@ -23,7 +23,7 @@ function UTCtoDate(utc){
|
|||
return d;
|
||||
}
|
||||
function scoregraph () {
|
||||
$.get('/top/10', function( data ) {
|
||||
$.get(script_root + '/top/10', function( data ) {
|
||||
var scores = $.parseJSON(JSON.stringify(data));
|
||||
scores = scores['scores'];
|
||||
if (Object.keys(scores).length == 0 ){
|
||||
|
@ -72,4 +72,4 @@ scoregraph();
|
|||
|
||||
window.onresize = function () {
|
||||
Plotly.Plots.resize(document.getElementById('score-graph'));
|
||||
};
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ function scoregraph() {
|
|||
var times = []
|
||||
var scores = []
|
||||
var teamname = $('#team-id').text()
|
||||
$.get('/solves/' + teamid(), function (data) {
|
||||
$.get(script_root + '/solves/' + teamid(), function (data) {
|
||||
var solves = $.parseJSON(JSON.stringify(data));
|
||||
solves = solves['solves'];
|
||||
|
||||
|
@ -57,7 +57,7 @@ function scoregraph() {
|
|||
|
||||
function keys_percentage_graph() {
|
||||
// Solves and Fails pie chart
|
||||
$.get('/fails/' + teamid(), function (data) {
|
||||
$.get(script_root + '/fails/' + teamid(), function (data) {
|
||||
var res = $.parseJSON(JSON.stringify(data));
|
||||
var solves = res['solves'];
|
||||
var fails = res['fails'];
|
||||
|
@ -85,7 +85,7 @@ function keys_percentage_graph() {
|
|||
}
|
||||
|
||||
function category_breakdown_graph() {
|
||||
$.get('/solves/' + teamid(), function (data) {
|
||||
$.get(script_root + '/solves/' + teamid(), function (data) {
|
||||
var solves = $.parseJSON(JSON.stringify(data));
|
||||
solves = solves['solves'];
|
||||
|
||||
|
@ -136,4 +136,4 @@ window.onresize = function () {
|
|||
Plotly.Plots.resize(document.getElementById('keys-pie-graph'));
|
||||
Plotly.Plots.resize(document.getElementById('categories-pie-graph'));
|
||||
Plotly.Plots.resize(document.getElementById('score-graph'));
|
||||
};
|
||||
};
|
||||
|
|
|
@ -52,4 +52,4 @@ function colorhash (x) {
|
|||
|
||||
function htmlentities(string) {
|
||||
return $('<div/>').text(string).html();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,15 +5,18 @@
|
|||
<title>Admin Panel</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="/static/css/vendor/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link href='/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
||||
<link href='/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" type="text/css" href="/static/admin/css/style.css">
|
||||
<script src="/static/js/vendor/moment.min.js"></script>
|
||||
<link rel="shortcut icon" href="{{ request.script_root }}/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="{{ request.script_root }}/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
||||
<link rel="stylesheet" href="{{ request.script_root }}/static/css/style.css">
|
||||
<link href='{{ request.script_root }}/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
||||
<link href='{{ request.script_root }}/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/style.css">
|
||||
<script src="{{ request.script_root }}/static/js/vendor/moment.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var script_root = "{{ request.script_root }}";
|
||||
</script>
|
||||
{% block stylesheets %} {% endblock %}
|
||||
</head>
|
||||
|
||||
|
@ -27,20 +30,20 @@
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a href="/" class="navbar-brand">CTFd</a>
|
||||
<a href="{{ request.script_root }}/" class="navbar-brand">CTFd</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
|
||||
<ul class="nav navbar-nav navbar-nav-right">
|
||||
<li><a href="/admin/graphs">Graphs</a></li>
|
||||
<li><a href="/admin/pages">Pages</a></li>
|
||||
<li><a href="/admin/teams">Teams</a></li>
|
||||
<li><a href="/admin/scoreboard">Scoreboard</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/graphs">Graphs</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/pages">Pages</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/teams">Teams</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/scoreboard">Scoreboard</a></li>
|
||||
{% if can_create_container() %}
|
||||
<li><a href="/admin/containers">Containers</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/containers">Containers</a></li>
|
||||
{% endif %}
|
||||
<li><a href="/admin/chals">Challenges</a></li>
|
||||
<li><a href="/admin/statistics">Statistics</a></li>
|
||||
<li><a href="/admin/config">Config</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/chals">Challenges</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/statistics">Statistics</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin/config">Config</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -50,9 +53,9 @@
|
|||
{% block content %} {% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<script src="/static/js/vendor/jquery.min.js"></script>
|
||||
<script src="/static/js/vendor/marked.min.js"></script>
|
||||
<script src="/static/js/vendor/bootstrap.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/jquery.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/marked.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/bootstrap.min.js"></script>
|
||||
{% block scripts %} {% endblock %}
|
||||
</body>
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<h3>New Challenge</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="/admin/chal/new" enctype="multipart/form-data">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/chal/new" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" class="form-control" name="name" placeholder="Enter challenge name">
|
||||
|
@ -105,7 +105,7 @@
|
|||
<h3 class="chal-title text-center"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="/admin/chal/update">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/chal/update">
|
||||
<input name='nonce' type='hidden' value="{{ nonce }}">
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -168,7 +168,7 @@
|
|||
<h3>Delete Challenge</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="/admin/chal/delete">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/chal/delete">
|
||||
<input type="hidden" name="nonce" value="{{ nonce }}">
|
||||
<input type="hidden" name="id" class="chal-id">
|
||||
<div class="small-6 small-centered text-center columns">
|
||||
|
@ -190,7 +190,7 @@
|
|||
<h3>Keys</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="/admin/keys" style="text-align:center">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/keys" style="text-align:center">
|
||||
<a href="#" id="create-key" class="btn btn-primary" style="margin-bottom:15px;">New Key</a>
|
||||
<input name='nonce' type='hidden' value="{{ nonce }}">
|
||||
<input id="keys-chal" name='chal' type='hidden'>
|
||||
|
@ -212,7 +212,7 @@
|
|||
<h3>Files</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="/admin/files/" enctype="multipart/form-data">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/files/" enctype="multipart/form-data">
|
||||
<input name='nonce' type='hidden' value="{{ nonce }}">
|
||||
<input id="files-chal" name='chal' type='hidden'>
|
||||
<input name='method' type='hidden' value='upload'>
|
||||
|
@ -298,7 +298,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/admin/js/multi-modal.js"></script>
|
||||
<script src="/static/admin/js/chalboard.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/admin/js/multi-modal.js"></script>
|
||||
<script src="{{ request.script_root }}/static/admin/js/chalboard.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="container-modal-label">Create Container</h4>
|
||||
</div>
|
||||
<form method="POST" action="/admin/containers/new" enctype="multipart/form-data">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/containers/new" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<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 team" id="{{ solve.teamid }}"><a href="{{ request.script_root }}/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-time"><script>document.write( moment({{ solve.date|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||
<td class="text-center">{{ solve.flag }}</td>
|
||||
|
@ -61,24 +61,24 @@
|
|||
{% if pages > 1 %}
|
||||
<div class="text-center">Page
|
||||
<br>
|
||||
{% if curr_page != 1 %}<a href="/admin/correct_keys/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% if curr_page != 1 %}<a href="{{ request.script_root }}/admin/correct_keys/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% for page in range(1, pages + 1) %}
|
||||
{% if curr_page != page %}
|
||||
<a href="/admin/correct_keys/{{ page }}">{{ page }}</a>
|
||||
<a href="{{ request.script_root }}/admin/correct_keys/{{ page }}">{{ page }}</a>
|
||||
{% else %}
|
||||
<b>{{ page }}</b>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if curr_page != pages %}<a href="/admin/correct_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
<a href="">
|
||||
{% if curr_page != pages %}<a href="{{ request.script_root }}/admin/correct_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
<a href="{{ request.script_root }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/admin/js/team.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
|
||||
<script>
|
||||
$('#delete-solve').click(function(e){
|
||||
e.preventDefault();
|
||||
|
@ -95,7 +95,7 @@
|
|||
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 form').attr('action', '{{ request.script_root }}/admin/solves/'+team+'/'+chal+'/delete');
|
||||
$('#confirm').modal('show');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block stylesheets %}
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/vendor/codemirror.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/css/vendor/codemirror.min.css">
|
||||
<style>
|
||||
.row-fluid { margin: 25px; padding-bottom: 25px; }
|
||||
</style>
|
||||
|
@ -38,7 +38,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/vendor/codemirror.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/codemirror.min.js"></script>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("admin-pages-editor"), {
|
||||
lineNumbers: true,
|
||||
|
@ -49,7 +49,7 @@
|
|||
});
|
||||
|
||||
$('#page-edit').submit(function (e){
|
||||
$(this).attr('action', '/admin/pages/'+$('#route').val());
|
||||
$(this).attr('action', '{{ request.script_root }}/admin/pages/'+$('#route').val());
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
display: block;
|
||||
}
|
||||
</style>
|
||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
// $.distint(array)
|
||||
// Unique elements in array
|
||||
|
@ -59,7 +59,7 @@
|
|||
}
|
||||
|
||||
function solves_graph() {
|
||||
$.get('/admin/graphs/solves', function(data){
|
||||
$.get('{{ request.script_root }}/admin/graphs/solves', function(data){
|
||||
var solves = $.parseJSON(JSON.stringify(data));
|
||||
var chals = [];
|
||||
var counts = [];
|
||||
|
@ -89,7 +89,7 @@
|
|||
|
||||
function keys_percentage_graph(){
|
||||
// Solves and Fails pie chart
|
||||
$.get('/admin/fails/all', function(data){
|
||||
$.get('{{ request.script_root }}/admin/fails/all', function(data){
|
||||
var res = $.parseJSON(JSON.stringify(data));
|
||||
var solves = res['solves'];
|
||||
var fails = res['fails'];
|
||||
|
@ -116,7 +116,7 @@
|
|||
}
|
||||
|
||||
function category_breakdown_graph(){
|
||||
$.get('/admin/graphs/categories', function(data){
|
||||
$.get('{{ request.script_root }}/admin/graphs/categories', function(data){
|
||||
res = $.parseJSON(JSON.stringify(data));
|
||||
res = res['categories']
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block stylesheets %}
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/vendor/codemirror.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/css/vendor/codemirror.min.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
@ -38,7 +38,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<h3>HTML Pages <a href="/admin/pages?mode=create"><i class="fa fa-plus"></i></a></h3>
|
||||
<h3>HTML Pages <a href="{{ request.script_root }}/admin/pages?mode=create"><i class="fa fa-plus"></i></a></h3>
|
||||
<table id="pages" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<tbody>
|
||||
{% for route in routes %}
|
||||
<tr name="{{ route.route }}">
|
||||
<td class="route-name"><a href="/admin/pages/{{ route.route }}">{{ route.route }}</a></td>
|
||||
<td class="route-name"><a href="{{ request.script_root }}/admin/pages/{{ route.route }}">{{ route.route }}</a></td>
|
||||
<td class="text-center"><i class="fa fa-times"></i></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -60,7 +60,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/vendor/codemirror.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/codemirror.min.js"></script>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("pages-editor"), {
|
||||
lineNumbers: true,
|
||||
|
@ -85,7 +85,7 @@ function load_confirm_modal(route){
|
|||
var modal = $('#confirm')
|
||||
modal.find('input[name=route]').val(route)
|
||||
modal.find('#confirm-route-name').text(route)
|
||||
$('#confirm form').attr('action', '/admin/page/'+route+'/delete');
|
||||
$('#confirm form').attr('action', '{{ request.script_root }}/admin/page/'+route+'/delete');
|
||||
$('#confirm').modal();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,16 +17,16 @@
|
|||
{% for team in teams %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
<td><a href="/admin/team/{{ team.teamid }}">{{ team.name }}</a></td>
|
||||
<td><a href="{{ request.script_root }}/admin/team/{{ team.teamid }}">{{ team.name }}</a></td>
|
||||
<td>{{ team.score }}</td>
|
||||
<td>
|
||||
{% if not team.banned %}
|
||||
<form method="POST" style="margin:0;" action="/admin/team/{{ team.teamid }}/ban">
|
||||
<form method="POST" style="margin:0;" action="{{ request.script_root }}/admin/team/{{ team.teamid }}/ban">
|
||||
<a onclick="$(this).parent().submit()">Ban</a>
|
||||
<input type="hidden" value="{{ nonce }}" name="nonce">
|
||||
</form>
|
||||
{%else %}
|
||||
<form method="POST" style="margin:0;" action="/admin/team/{{ team.teamid }}/unban">
|
||||
<form method="POST" style="margin:0;" action="{{ request.script_root }}/admin/team/{{ team.teamid }}/unban">
|
||||
<a onclick="$(this).parent().submit()">Unban</a>
|
||||
<input type="hidden" value="{{ nonce }}" name="nonce">
|
||||
</form>
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
<h1>Statistics</h1>
|
||||
|
||||
<h3><b>{{ team_count }}</b> teams registered</h3>
|
||||
<h3><b>{{ wrong_count }}</b> <a href="wrong_keys/1">wrong keys</a> submitted</h3>
|
||||
<h3><b>{{ solve_count }}</b> <a href="correct_keys/1">right keys</a> submitted</h3>
|
||||
<h3><b>{{ wrong_count }}</b> <a href="{{ request.script_root }}/admin/wrong_keys/1">wrong keys</a> submitted</h3>
|
||||
<h3><b>{{ solve_count }}</b> <a href="{{ request.script_root }}/admin/correct_keys/1">right keys</a> submitted</h3>
|
||||
<h3><b>{{ challenge_count }}</b> challenges</h3>
|
||||
{% 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].name }}</b> with {{ most_solved[1] }}</b> solves</h3>
|
||||
{% endif %}
|
||||
{% if least_solved %}
|
||||
<h3>Least solved: <b>{{ least_solved[0].name }}</b> with {{ least_solved[1] }}</b> solves</h3>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<h4 class="modal-title" id="create-award-label">Create Award</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="award-create-form" method="POST" action="/admin/awards/add">
|
||||
<form id="award-create-form" method="POST" action="{{ request.script_root }}/admin/awards/add">
|
||||
<div class="form-group">
|
||||
<label for="award-name-input">Name</label>
|
||||
<input type="text" class="form-control" id="award-name-input" name="name" placeholder="Enter award name">
|
||||
|
@ -62,7 +62,7 @@
|
|||
<h3 id="confirm-title">Delete Key</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="/admin/chal/delete">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/chal/delete">
|
||||
<input id="nonce" type="hidden" name="nonce" value="{{ nonce }}">
|
||||
<div class="small-6 small-centered text-center columns">
|
||||
<p id="confirm-description"></p>
|
||||
|
@ -104,8 +104,8 @@
|
|||
<tbody>
|
||||
{% for addr in addrs %}
|
||||
<tr>
|
||||
<td class="text-center">{{ addr.ip|long2ip }}</td>
|
||||
<td class="text-center solve-time"><script>document.write( moment({{ addr.date|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||
<td class="text-center">{{ addr[0]|long2ip }}</td>
|
||||
<td class="text-center solve-time"><script>document.write( moment({{ addr[1]|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -221,10 +221,10 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/vendor/moment.min.js"></script>
|
||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/admin/js/team.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/moment.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
|
||||
<script>
|
||||
$('#delete-solve').click(function (e) {
|
||||
e.preventDefault();
|
||||
|
@ -270,7 +270,7 @@
|
|||
description.find('#confirm-chal-name').text(chal_name);
|
||||
description = description.html()
|
||||
|
||||
var action = '/admin/solves/' + team + '/' + chal + '/delete';
|
||||
var action = '{{ request.script_root }}/admin/solves/' + team + '/' + chal + '/delete';
|
||||
} else if (type == 'chal-wrong') {
|
||||
var title = 'Delete Wrong Key';
|
||||
var description = "<span>Are you sure you want to delete " +
|
||||
|
@ -285,12 +285,12 @@
|
|||
description.find('#confirm-chal-name').text(chal_name);
|
||||
description = description.html()
|
||||
|
||||
var action = '/admin/wrong_keys/' + team + '/' + chal + '/delete';
|
||||
var action = '{{ request.script_root }}/admin/wrong_keys/' + team + '/' + chal + '/delete';
|
||||
} else if (type == 'award-row') {
|
||||
var title = 'Delete Award';
|
||||
var description = "<span>Are you sure you want to delete the " +
|
||||
"<strong>{0}</strong> award?</span>".format(chal_name);
|
||||
var action = '/admin/awards/{0}/delete'.format(chal);
|
||||
var action = '{{ request.script_root }}/admin/awards/{0}/delete'.format(chal);
|
||||
}
|
||||
|
||||
var msg = {
|
||||
|
@ -323,7 +323,7 @@
|
|||
description.find('#confirm-chal-name').text(chal_name);
|
||||
description = description.html()
|
||||
|
||||
var action = '/admin/solves/' + team + '/' + chal + '/solve';
|
||||
var action = '{{request.script_root }}/admin/solves/' + team + '/' + chal + '/solve';
|
||||
|
||||
var msg = {
|
||||
title : title,
|
||||
|
|
|
@ -62,7 +62,7 @@ input[type="checkbox"] { margin: 0px !important; position: relative; top: 5px; }
|
|||
<h2 class="text-center">Edit User</h2>
|
||||
</div>
|
||||
<div class="modal-body" style="padding:20px; height:525px;">
|
||||
<form method="POST" action="/admin/teams/">
|
||||
<form method="POST" action="{{ request.script_root }}/admin/teams/">
|
||||
<input type="hidden" name="nonce" value="{{ nonce }}">
|
||||
<input type="hidden" name="id">
|
||||
<div class="form-group">
|
||||
|
@ -123,7 +123,7 @@ input[type="checkbox"] { margin: 0px !important; position: relative; top: 5px; }
|
|||
{% for team in teams %}
|
||||
<tr name="{{ team.id }}">
|
||||
<td class="team-id">{{ team.id }}</td>
|
||||
<td class="team-name"><a href="/admin/team/{{ team.id }}">{{ team.name | truncate(32) }}</a>
|
||||
<td class="team-name"><a href="{{ request.script_root }}/admin/team/{{ team.id }}">{{ team.name | truncate(32) }}</a>
|
||||
</td>
|
||||
<td class="team-email">{{ team.email | truncate(32) }}</td>
|
||||
<td class="team-website">{% if team.website and team.website.startswith('http') %}<a href="{{ team.website }}">{{ team.website | truncate(32) }}</a>{% endif %}
|
||||
|
@ -150,15 +150,15 @@ input[type="checkbox"] { margin: 0px !important; position: relative; top: 5px; }
|
|||
{% if pages > 1 %}
|
||||
<div class="text-center">Page
|
||||
<br>
|
||||
{% if curr_page != 1 %}<a href="/admin/teams/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% if curr_page != 1 %}<a href="{{ request.script_root }}/admin/teams/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% for page in range(1, pages + 1) %}
|
||||
{% if curr_page != page %}
|
||||
<a href="/admin/teams/{{ page }}">{{ page }}</a>
|
||||
<a href="{{ request.script_root }}/admin/teams/{{ page }}">{{ page }}</a>
|
||||
{% else %}
|
||||
<b>{{ page }}</b>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if curr_page != pages %}<a href="/admin/teams/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
{% if curr_page != pages %}<a href="{{ request.script_root }}/admin/teams/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -175,7 +175,7 @@ function load_update_modal(id, name, email, website, affiliation, country){
|
|||
modal_form.find('input[name=website]').val(website)
|
||||
modal_form.find('input[name=affiliation]').val(affiliation)
|
||||
modal_form.find('input[name=country]').val(country)
|
||||
$('#user form').attr('action', '/admin/team/'+id)
|
||||
$('#user form').attr('action', '{{ request.script_root }}/admin/team/'+id)
|
||||
$('#user').modal("show");
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ $('.team-admin input').on('change', function(){
|
|||
var nonce = $('#nonce').val()
|
||||
console.log(admin)
|
||||
|
||||
$.post('/admin/team/'+id, {'admin':admin, 'nonce':nonce});
|
||||
$.post('{{ request.script_root }}/admin/team/'+id, {'admin':admin, 'nonce':nonce});
|
||||
})
|
||||
|
||||
$('#send-user-email').click(function(e){
|
||||
|
@ -260,7 +260,7 @@ function load_confirm_modal(id, name){
|
|||
var modal = $('#confirm')
|
||||
modal.find('input[name=id]').val(id)
|
||||
modal.find('#confirm-team-name').text(name)
|
||||
$('#confirm form').attr('action', '/admin/team/'+id+'/delete');
|
||||
$('#confirm form').attr('action', '{{ request.script_root }}/admin/team/'+id+'/delete');
|
||||
$('#confirm').modal();
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,7 @@ function load_email_modal(id){
|
|||
modal.find('textarea').val("")
|
||||
modal.find('input[name=id]').val(id)
|
||||
$('#email-user-errors').empty()
|
||||
$('#email-user form').attr('action', '/admin/team/'+id+'/mail');
|
||||
$('#email-user form').attr('action', '{{ request.script_root }}/admin/team/'+id+'/mail');
|
||||
$('#email-user').modal();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
<tbody>
|
||||
{% for wrong_key in wrong_keys %}
|
||||
<tr>
|
||||
<td class="text-center team" id="{{ wrong_key.team }}"><a href="/admin/team/{{ wrong_key.team }}">{{ wrong_key.team_name }}</a>
|
||||
<td class="text-center team" id="{{ wrong_key.team }}"><a href="{{ request.script_root }}/admin/team/{{ wrong_key.team }}">{{ wrong_key.team_name }}</a>
|
||||
<td class="text-center chal" id="{{ wrong_key.chalid }}">{{ wrong_key.chal_name }}</td>
|
||||
<td class="text-center solve-time"><script>document.write( moment({{ wrong_key.date|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||
<td class="text-center">{{ wrong_key.flag }}</td>
|
||||
|
@ -68,24 +68,24 @@
|
|||
{% if pages > 1 %}
|
||||
<div class="text-center">Page
|
||||
<br>
|
||||
{% if curr_page != 1 %}<a href="/admin/wrong_keys/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% if curr_page != 1 %}<a href="{{ request.script_root }}/admin/wrong_keys/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% for page in range(1, pages + 1) %}
|
||||
{% if curr_page != page %}
|
||||
<a href="/admin/wrong_keys/{{ page }}">{{ page }}</a>
|
||||
<a href="{{ request.script_root }}/admin/wrong_keys/{{ page }}">{{ page }}</a>
|
||||
{% else %}
|
||||
<b>{{ page }}</b>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if curr_page != pages %}<a href="/admin/wrong_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
<a href="">
|
||||
{% if curr_page != pages %}<a href="{{ request.script_root }}/admin/wrong_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
<a href="{{ request.script_root }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/admin/js/team.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
|
||||
<script>
|
||||
$('#delete-solve').click(function (e) {
|
||||
e.preventDefault();
|
||||
|
@ -102,7 +102,7 @@
|
|||
var modal = $('#confirm')
|
||||
modal.find('#confirm-team-name').text(team_name);
|
||||
modal.find('#confirm-chal-name').text(chal_name);
|
||||
$('#confirm form').attr('action', '/admin/wrong_keys/' + team + '/' + chal + '/delete');
|
||||
$('#confirm form').attr('action', '{{ request.script_root }}/admin/wrong_keys/' + team + '/' + chal + '/delete');
|
||||
$('#confirm').modal('show');
|
||||
}
|
||||
|
||||
|
|
|
@ -4,16 +4,19 @@
|
|||
<title>{{ ctf_name() }}</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="/static/css/vendor/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
||||
<link href='/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
||||
<link href='/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/user.css">
|
||||
<link rel="shortcut icon" href="{{ request.script_root }}/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="{{ request.script_root }}/static/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
||||
<link href='{{ request.script_root }}/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
||||
<link href='{{ request.script_root }}/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="{{ request.script_root }}/static/css/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/user.css">
|
||||
{% block stylesheets %}{% endblock %}
|
||||
<script src="/static/js/vendor/moment.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/moment.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var script_root = "{{ request.script_root }}";
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="body-container">
|
||||
|
@ -25,31 +28,31 @@
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a href="/" class="navbar-brand">{{ ctf_name() }}</a>
|
||||
<a href="{{ request.script_root }}/" class="navbar-brand">{{ ctf_name() }}</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
|
||||
<ul class="nav navbar-nav">
|
||||
{% for page in pages() %}
|
||||
<li><a href="/{{ page.route }}">{{ page.route|title }}</a></li>
|
||||
<li><a href="{{ request.script_root }}/{{ page.route }}">{{ page.route|title }}</a></li>
|
||||
{% endfor %}
|
||||
<li><a href="/teams">Teams</a></li>
|
||||
<li><a href="/scoreboard">Scoreboard</a></li>
|
||||
<li><a href="/challenges">Challenges</a></li>
|
||||
<li><a href="{{ request.script_root }}/teams">Teams</a></li>
|
||||
<li><a href="{{ request.script_root }}/scoreboard">Scoreboard</a></li>
|
||||
<li><a href="{{ request.script_root }}/challenges">Challenges</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{% if username is defined %}
|
||||
{% if admin %}
|
||||
<li><a href="/admin">Admin</a></li>
|
||||
<li><a href="{{ request.script_root }}/admin">Admin</a></li>
|
||||
{% endif %}
|
||||
<li><a href="/team/{{ id }}">Team</a></li>
|
||||
<li><a href="/profile">Profile</a></li>
|
||||
<li><a href="/logout">Logout</a></li>
|
||||
<li><a href="{{ request.script_root }}/team/{{ id }}">Team</a></li>
|
||||
<li><a href="{{ request.script_root }}/profile">Profile</a></li>
|
||||
<li><a href="{{ request.script_root }}/logout">Logout</a></li>
|
||||
{% else %}
|
||||
{% if can_register() %}
|
||||
<li><a href="/register">Register</a></li>
|
||||
<li><a href="{{ request.script_root }}/register">Register</a></li>
|
||||
<li><a style="padding-left:0px;padding-right:0px;">|</a></li>
|
||||
{% endif %}
|
||||
<li><a href="/login">Login</a></li>
|
||||
<li><a href="{{ request.script_root }}/login">Login</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -60,9 +63,9 @@
|
|||
{% endblock %}
|
||||
|
||||
</div>
|
||||
<script src="/static/js/vendor/jquery.min.js"></script>
|
||||
<script src="/static/js/vendor/marked.min.js"></script>
|
||||
<script src="/static/js/vendor/bootstrap.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/jquery.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/marked.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/bootstrap.min.js"></script>
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/js/chalboard.js"></script>
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/chalboard.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -44,6 +44,6 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
</div>
|
||||
<div class="done-row row">
|
||||
<div class="col-md-6" style="padding-left:0px">
|
||||
<a class="pull-left align-text-to-button" href="/reset_password">Forgot your password?</a>
|
||||
<a class="pull-left align-text-to-button" href="{{ request.script_root }}/reset_password">Forgot your password?</a>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button>
|
||||
|
@ -67,6 +67,6 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -132,5 +132,5 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
<script>
|
||||
if (window.location.hash == "#frame"){
|
||||
$('.top-bar').hide()
|
||||
|
|
|
@ -55,5 +55,5 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
{% for team in teams %}
|
||||
<tr><td>{{ loop.index }}</td><td><a href="/team/{{ team.teamid }}">{{ team.name }}</a></td><td>{{ team.score }}</td></tr>
|
||||
<tr><td>{{ loop.index }}</td><td><a href="{{ request.script_root }}/team/{{ team.teamid }}">{{ team.name }}</a></td><td>{{ team.score }}</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -31,7 +31,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/js/scoreboard.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/scoreboard.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -63,5 +63,5 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/style.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
<tbody>
|
||||
{% for solve in solves %}
|
||||
<tr>
|
||||
<td><a href="/challenges#{{ solve.chal.name }}">{{ solve.chal.name }}</a></td>
|
||||
<td><a href="{{ request.script_root }}/challenges#{{ solve.chal.name }}">{{ solve.chal.name }}</a></td>
|
||||
<td class="hidden-xs">{{ solve.chal.category }}</td><td>{{ solve.chal.value }}</td>
|
||||
<td class="solve-time"><script>document.write( moment({{ solve.date|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||
</tr>
|
||||
|
@ -81,7 +81,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="/static/js/utils.js"></script>
|
||||
<script src="/static/js/team.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||
<script src="{{ request.script_root }}/static/js/team.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<tbody>
|
||||
{% for team in teams %}
|
||||
<tr>
|
||||
<td><a href="/team/{{ team.id }}">{{ team.name }}</a></td>
|
||||
<td><a href="{{ request.script_root }}/team/{{ team.id }}">{{ team.name }}</a></td>
|
||||
<td>{% if team.website and team.website.startswith('http://') %}<a href="{{ team.website }}">{{ team.website }}</a>{% endif %}</td>
|
||||
<td><span>{% if team.affiliation %}{{ team.affiliation }}{% endif %}</span></td>
|
||||
<td class="hidden-xs"><span>{% if team.country %}{{ team.country }}{% endif %}</span></td>
|
||||
|
@ -33,16 +33,16 @@
|
|||
{% if team_pages > 1 %}
|
||||
<div class="text-center">Page
|
||||
<br>
|
||||
{% if curr_page != 1 %}<a href="/teams/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% if curr_page != 1 %}<a href="{{ request.script_root }}/teams/{{ curr_page-1 }}"><<<</a>{% endif %}
|
||||
{% for page in range(1, team_pages + 1) %}
|
||||
{% if curr_page != page %}
|
||||
<a href="/teams/{{ page }}">{{ page }}</a>
|
||||
<a href="{{ request.script_root }}/teams/{{ page }}">{{ page }}</a>
|
||||
{% else %}
|
||||
<b>{{page}}</b>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if curr_page != team_pages %}<a href="/teams/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
<a href="">
|
||||
{% if curr_page != team_pages %}<a href="{{ request.script_root }}/teams/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||
<a href="{{ request.script_root }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,7 @@ views = Blueprint('views', __name__)
|
|||
|
||||
@views.before_request
|
||||
def redirect_setup():
|
||||
if request.path == "/static/css/style.css":
|
||||
if request.path.startswith("/static"):
|
||||
return
|
||||
if not is_setup() and request.path != "/setup":
|
||||
return redirect(url_for('views.setup'))
|
||||
|
@ -50,15 +50,15 @@ def setup():
|
|||
|
||||
## Index page
|
||||
page = Pages('index', """<div class="container main-container">
|
||||
<img class="logo" src="/static/img/logo.png" />
|
||||
<img class="logo" src="{0}/static/img/logo.png" />
|
||||
<h3 class="text-center">
|
||||
Welcome to a cool CTF framework written by <a href="https://github.com/ColdHeat">Kevin Chung</a> of <a href="https://github.com/isislab">@isislab</a>
|
||||
</h3>
|
||||
|
||||
<h4 class="text-center">
|
||||
<a href="/admin">Click here</a> to login and setup your CTF
|
||||
<a href="{0}/admin">Click here</a> to login and setup your CTF
|
||||
</h4>
|
||||
</div>""")
|
||||
</div>""".format(request.script_root))
|
||||
|
||||
#max attempts per challenge
|
||||
max_tries = set_config("max_tries",0)
|
||||
|
@ -89,9 +89,9 @@ def setup():
|
|||
db.session.add(admin)
|
||||
db.session.commit()
|
||||
app.setup = False
|
||||
return redirect('/')
|
||||
return redirect(url_for('views.static_html'))
|
||||
return render_template('setup.html', nonce=session.get('nonce'))
|
||||
return redirect('/')
|
||||
return redirect(url_for('views.static_html'))
|
||||
|
||||
|
||||
# Custom CSS handler
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# UWSGI Configuration File
|
||||
# Install uwsgi (sudo apt-get install uwsgi), copy this file to
|
||||
# /etc/uwsgi/apps-available and then link it in /etc/uwsgi/apps-enabled
|
||||
# Only two lines below (commented) need to be changed for your config.
|
||||
# Then, you can use something like the following in your nginx config:
|
||||
#
|
||||
# # SERVER_ROOT is not / (e.g. /ctf)
|
||||
# location = /ctf { rewrite ^ /ctf/; }
|
||||
# location /ctf {
|
||||
# include uwsgi_params;
|
||||
# uwsgi_pass unix:/run/uwsgi/app/ctfd/socket;
|
||||
# }
|
||||
#
|
||||
# # SERVER_ROOT is /
|
||||
# location / {
|
||||
# include uwsgi_params;
|
||||
# wsgi_pass unix:/run/uwsgi/app/ctfd/socket;
|
||||
# }
|
||||
[uwsgi]
|
||||
# Where you've put CTFD
|
||||
chdir = /var/www/ctfd/
|
||||
# If SCRIPT_ROOT is not /
|
||||
#mount = /ctf=wsgi.py
|
||||
# SCRIPT_ROOT is /
|
||||
mount = /=wsgi.py
|
||||
|
||||
# You shouldn't need to change anything past here
|
||||
plugin = python
|
||||
module = wsgi
|
||||
|
||||
master = true
|
||||
processes = 1
|
||||
threads = 1
|
||||
|
||||
vacuum = true
|
||||
|
||||
manage-script-name = true
|
||||
wsgi-file = wsgi.py
|
||||
callable = app
|
||||
|
||||
die-on-term = true
|
||||
|
||||
# If you're not on debian/ubuntu, replace with uid/gid of web user
|
||||
uid = www-data
|
||||
gid = www-data
|
||||
|
Loading…
Reference in New Issue