mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 22:14:25 +01:00
Allow CTFd to run with script_root != '/' and PostgreSQL (#125)
Also, Add WSGI config example
This commit is contained in:
committed by
Kevin Chung
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 itsdangerous import TimedSerializer, BadTimeSignature
|
||||||
from sqlalchemy.sql import and_, or_, not_
|
from sqlalchemy.sql import and_, or_, not_
|
||||||
from sqlalchemy.sql.expression import union_all
|
from sqlalchemy.sql.expression import union_all
|
||||||
|
from sqlalchemy.sql.functions import coalesce
|
||||||
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
|
||||||
@@ -18,6 +19,8 @@ import json
|
|||||||
import datetime
|
import datetime
|
||||||
import calendar
|
import calendar
|
||||||
|
|
||||||
|
from scoreboard import get_standings
|
||||||
|
|
||||||
admin = Blueprint('admin', __name__)
|
admin = Blueprint('admin', __name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -276,12 +279,12 @@ def delete_container(container_id):
|
|||||||
def new_container():
|
def new_container():
|
||||||
name = request.form.get('name')
|
name = request.form.get('name')
|
||||||
if set(name) <= set('abcdefghijklmnopqrstuvwxyz0123456789-_'):
|
if set(name) <= set('abcdefghijklmnopqrstuvwxyz0123456789-_'):
|
||||||
return redirect('/admin/containers')
|
return redirect(url_for('admin.list_container'))
|
||||||
buildfile = request.form.get('buildfile')
|
buildfile = request.form.get('buildfile')
|
||||||
files = request.files.getlist('files[]')
|
files = request.files.getlist('files[]')
|
||||||
create_image(name=name, buildfile=buildfile, files=files)
|
create_image(name=name, buildfile=buildfile, files=files)
|
||||||
run_image(name)
|
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':
|
if request.method == 'POST':
|
||||||
chals = Challenges.query.add_columns('id', 'name', 'value', 'description', 'category', 'hidden').order_by(Challenges.value).all()
|
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(
|
Teams.banned == False).group_by(
|
||||||
Solves.teamid).count()
|
Solves.teamid).count()
|
||||||
|
|
||||||
@@ -427,7 +430,7 @@ def admin_teams(page):
|
|||||||
page_start = results_per_page * ( page - 1 )
|
page_start = results_per_page * ( page - 1 )
|
||||||
page_end = results_per_page * ( page - 1 ) + results_per_page
|
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]
|
count = db.session.query(db.func.count(Teams.id)).first()[0]
|
||||||
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, curr_page=page)
|
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()
|
solves = Solves.query.filter_by(teamid=teamid).all()
|
||||||
solve_ids = [s.chalid for s in solves]
|
solve_ids = [s.chalid for s in solves]
|
||||||
missing = Challenges.query.filter( not_(Challenges.id.in_(solve_ids) ) ).all()
|
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()
|
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()
|
awards = Awards.query.filter_by(teamid=teamid).order_by(Awards.date.asc()).all()
|
||||||
score = user.score()
|
score = user.score()
|
||||||
@@ -452,10 +457,12 @@ def admin_team(teamid):
|
|||||||
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:
|
||||||
admin_user = 1 if admin_user == "true" else 0
|
admin_user = True if admin_user == 'true' else False
|
||||||
user.admin = admin_user
|
user.admin = admin_user
|
||||||
|
# Set user.banned to hide admins from scoreboard
|
||||||
user.banned = admin_user
|
user.banned = admin_user
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
db.session.close()
|
||||||
return jsonify({'data': ['success']})
|
return jsonify({'data': ['success']})
|
||||||
|
|
||||||
name = request.form.get('name', None)
|
name = request.form.get('name', None)
|
||||||
@@ -545,35 +552,21 @@ def admin_graph(graph_type):
|
|||||||
json_data['categories'].append({'category':category, 'count':count})
|
json_data['categories'].append({'category':category, 'count':count})
|
||||||
return jsonify(json_data)
|
return jsonify(json_data)
|
||||||
elif graph_type == "solves":
|
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 = {}
|
json_data = {}
|
||||||
for chal, count in solves:
|
for chal, count, name in solves:
|
||||||
json_data[chal.chal.name] = count
|
json_data[name] = count
|
||||||
return jsonify(json_data)
|
return jsonify(json_data)
|
||||||
|
|
||||||
|
|
||||||
@admin.route('/admin/scoreboard')
|
@admin.route('/admin/scoreboard')
|
||||||
@admins_only
|
@admins_only
|
||||||
def admin_scoreboard():
|
def admin_scoreboard():
|
||||||
score = db.func.sum(Challenges.value).label('score')
|
standings = get_standings(admin=True)
|
||||||
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()
|
|
||||||
return render_template('admin/scoreboard.html', teams=standings)
|
return render_template('admin/scoreboard.html', teams=standings)
|
||||||
|
|
||||||
|
|
||||||
@@ -711,8 +704,17 @@ def admin_stats():
|
|||||||
wrong_count = db.session.query(db.func.count(WrongKeys.id)).first()[0]
|
wrong_count = db.session.query(db.func.count(WrongKeys.id)).first()[0]
|
||||||
solve_count = db.session.query(db.func.count(Solves.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]
|
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()
|
db.session.close()
|
||||||
|
|
||||||
|
|||||||
@@ -172,4 +172,4 @@ def login():
|
|||||||
def logout():
|
def logout():
|
||||||
if authed():
|
if authed():
|
||||||
session.clear()
|
session.clear()
|
||||||
return redirect('/')
|
return redirect(url_for('views.static_html'))
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def challenges_view():
|
|||||||
if view_after_ctf():
|
if view_after_ctf():
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return redirect('/')
|
return redirect(url_for('views.static_html'))
|
||||||
if get_config('verify_emails') and not is_verified():
|
if get_config('verify_emails') and not is_verified():
|
||||||
return redirect(url_for('auth.confirm_user'))
|
return redirect(url_for('auth.confirm_user'))
|
||||||
if can_view_challenges():
|
if can_view_challenges():
|
||||||
@@ -36,7 +36,7 @@ def chals():
|
|||||||
if view_after_ctf():
|
if view_after_ctf():
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return redirect('/')
|
return redirect(url_for('views.static_html'))
|
||||||
if can_view_challenges():
|
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()
|
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')
|
@challenges.route('/chals/solves')
|
||||||
def chals_per_solves():
|
def chals_per_solves():
|
||||||
if can_view_challenges():
|
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 = {}
|
json = {}
|
||||||
for chal, count in solves:
|
for chal, count, name in solves:
|
||||||
json[chal.chal.name] = count
|
json[name] = count
|
||||||
|
db.session.close()
|
||||||
return jsonify(json)
|
return jsonify(json)
|
||||||
return redirect(url_for('auth.login', next='chals/solves'))
|
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)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
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.BigInteger)
|
||||||
flag = db.Column(db.Text)
|
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')
|
||||||
|
|||||||
@@ -5,31 +5,37 @@ from sqlalchemy.sql.expression import union_all
|
|||||||
|
|
||||||
scoreboard = Blueprint('scoreboard', __name__)
|
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')
|
@scoreboard.route('/scoreboard')
|
||||||
def scoreboard_view():
|
def scoreboard_view():
|
||||||
if get_config('view_scoreboard_if_authed') and not authed():
|
if get_config('view_scoreboard_if_authed') and not authed():
|
||||||
return redirect(url_for('auth.login', next=request.path))
|
return redirect(url_for('auth.login', next=request.path))
|
||||||
score = db.func.sum(Challenges.value).label('score')
|
standings = get_standings()
|
||||||
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()
|
|
||||||
return render_template('scoreboard.html', teams=standings)
|
return render_template('scoreboard.html', teams=standings)
|
||||||
|
|
||||||
|
|
||||||
@@ -37,25 +43,7 @@ def scoreboard_view():
|
|||||||
def scores():
|
def scores():
|
||||||
if get_config('view_scoreboard_if_authed') and not authed():
|
if get_config('view_scoreboard_if_authed') and not authed():
|
||||||
return redirect(url_for('auth.login', next=request.path))
|
return redirect(url_for('auth.login', next=request.path))
|
||||||
score = db.func.sum(Challenges.value).label('score')
|
standings = get_standings()
|
||||||
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()
|
|
||||||
json = {'standings':[]}
|
json = {'standings':[]}
|
||||||
for i, x in enumerate(standings):
|
for i, x in enumerate(standings):
|
||||||
json['standings'].append({'pos':i+1, 'id':x.teamid, 'team':x.name,'score':int(x.score)})
|
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
|
count = 10
|
||||||
|
|
||||||
json = {'scores':{}}
|
json = {'scores':{}}
|
||||||
|
standings = get_standings(count=count)
|
||||||
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()
|
|
||||||
|
|
||||||
for team in standings:
|
for team in standings:
|
||||||
solves = Solves.query.filter_by(teamid=team.teamid).all()
|
solves = Solves.query.filter_by(teamid=team.teamid).all()
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ function loadchal(id, update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function submitkey(chal, key) {
|
function submitkey(chal, key) {
|
||||||
$.post("/admin/chal/" + chal, {
|
$.post(script_root + "/admin/chal/" + chal, {
|
||||||
key: key,
|
key: key,
|
||||||
nonce: $('#nonce').val()
|
nonce: $('#nonce').val()
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
@@ -55,7 +55,7 @@ function submitkey(chal, key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadkeys(chal){
|
function loadkeys(chal){
|
||||||
$.get('/admin/keys/' + chal, function(data){
|
$.get(script_root + '/admin/keys/' + chal, function(data){
|
||||||
$('#keys-chal').val(chal);
|
$('#keys-chal').val(chal);
|
||||||
keys = $.parseJSON(JSON.stringify(data));
|
keys = $.parseJSON(JSON.stringify(data));
|
||||||
keys = keys['keys'];
|
keys = keys['keys'];
|
||||||
@@ -84,7 +84,7 @@ function updatekeys(){
|
|||||||
$('#current-keys input[name*="key_type"]:checked').each(function(){
|
$('#current-keys input[name*="key_type"]:checked').each(function(){
|
||||||
vals.push($(this).val());
|
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)
|
loadchal(chal, true)
|
||||||
$('#update-keys').modal('hide');
|
$('#update-keys').modal('hide');
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ function loadtags(chal){
|
|||||||
$('#tags-chal').val(chal)
|
$('#tags-chal').val(chal)
|
||||||
$('#current-tags').empty()
|
$('#current-tags').empty()
|
||||||
$('#chal-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 = $.parseJSON(JSON.stringify(data))
|
||||||
tags = tags['tags']
|
tags = tags['tags']
|
||||||
for (var i = 0; i < tags.length; i++) {
|
for (var i = 0; i < tags.length; i++) {
|
||||||
@@ -108,11 +108,11 @@ function loadtags(chal){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deletetag(tagid){
|
function deletetag(tagid){
|
||||||
$.post('/admin/tags/'+tagid+'/delete', {'nonce': $('#nonce').val()});
|
$.post(script_root + '/admin/tags/'+tagid+'/delete', {'nonce': $('#nonce').val()});
|
||||||
}
|
}
|
||||||
|
|
||||||
function deletechal(chalid){
|
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(){
|
function updatetags(){
|
||||||
@@ -121,13 +121,13 @@ function updatetags(){
|
|||||||
$('#chal-tags > span > span').each(function(i, e){
|
$('#chal-tags > span > span').each(function(i, e){
|
||||||
tags.push($(e).text())
|
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)
|
loadchal(chal)
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadfiles(chal){
|
function loadfiles(chal){
|
||||||
$('#update-files form').attr('action', '/admin/files/'+chal)
|
$('#update-files form').attr('action', script_root+'/admin/files/'+chal)
|
||||||
$.get('/admin/files/' + chal, function(data){
|
$.get(script_root + '/admin/files/' + chal, function(data){
|
||||||
$('#files-chal').val(chal)
|
$('#files-chal').val(chal)
|
||||||
files = $.parseJSON(JSON.stringify(data));
|
files = $.parseJSON(JSON.stringify(data));
|
||||||
files = files['files']
|
files = files['files']
|
||||||
@@ -141,7 +141,7 @@ function loadfiles(chal){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deletefile(chal, file, elem){
|
function deletefile(chal, file, elem){
|
||||||
$.post('/admin/files/' + chal,{
|
$.post(script_root + '/admin/files/' + chal,{
|
||||||
'nonce': $('#nonce').val(),
|
'nonce': $('#nonce').val(),
|
||||||
'method': 'delete',
|
'method': 'delete',
|
||||||
'file': file
|
'file': file
|
||||||
@@ -155,7 +155,7 @@ function deletefile(chal, file, elem){
|
|||||||
|
|
||||||
function loadchals(){
|
function loadchals(){
|
||||||
$('#challenges').empty();
|
$('#challenges').empty();
|
||||||
$.post("/admin/chals", {
|
$.post(script_root + "/admin/chals", {
|
||||||
'nonce': $('#nonce').val()
|
'nonce': $('#nonce').val()
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
categories = [];
|
categories = [];
|
||||||
@@ -207,7 +207,7 @@ $('#submit-tags').click(function (e) {
|
|||||||
|
|
||||||
$('#delete-chal form').submit(function(e){
|
$('#delete-chal form').submit(function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$.post('/admin/chal/delete', $(this).serialize(), function(data){
|
$.post(script_root + '/admin/chal/delete', $(this).serialize(), function(data){
|
||||||
console.log(data)
|
console.log(data)
|
||||||
if (data){
|
if (data){
|
||||||
loadchals();
|
loadchals();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ function scoregraph () {
|
|||||||
var times = []
|
var times = []
|
||||||
var scores = []
|
var scores = []
|
||||||
var teamname = $('#team-id').text()
|
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));
|
var solves = $.parseJSON(JSON.stringify(data));
|
||||||
solves = solves['solves'];
|
solves = solves['solves'];
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ function scoregraph () {
|
|||||||
|
|
||||||
function keys_percentage_graph(){
|
function keys_percentage_graph(){
|
||||||
// Solves and Fails pie chart
|
// 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 res = $.parseJSON(JSON.stringify(data));
|
||||||
var solves = res['solves'];
|
var solves = res['solves'];
|
||||||
var fails = res['fails'];
|
var fails = res['fails'];
|
||||||
@@ -75,7 +75,7 @@ function keys_percentage_graph(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function category_breakdown_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));
|
var solves = $.parseJSON(JSON.stringify(data));
|
||||||
solves = solves['solves'];
|
solves = solves['solves'];
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ $("#answer-input").keyup(function(event){
|
|||||||
function submitkey(chal, key, nonce) {
|
function submitkey(chal, key, nonce) {
|
||||||
$('#submit-key').addClass("disabled-button");
|
$('#submit-key').addClass("disabled-button");
|
||||||
$('#submit-key').prop('disabled', true);
|
$('#submit-key').prop('disabled', true);
|
||||||
$.post("/chal/" + chal, {
|
$.post(script_root + "/chal/" + chal, {
|
||||||
key: key,
|
key: key,
|
||||||
nonce: nonce
|
nonce: nonce
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
@@ -103,7 +103,7 @@ function submitkey(chal, key, nonce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function marksolves() {
|
function marksolves() {
|
||||||
$.get('/solves', function (data) {
|
$.get(script_root + '/solves', function (data) {
|
||||||
solves = $.parseJSON(JSON.stringify(data));
|
solves = $.parseJSON(JSON.stringify(data));
|
||||||
for (var i = solves['solves'].length - 1; i >= 0; i--) {
|
for (var i = solves['solves'].length - 1; i >= 0; i--) {
|
||||||
id = solves['solves'][i].chalid;
|
id = solves['solves'][i].chalid;
|
||||||
@@ -118,7 +118,7 @@ function marksolves() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updatesolves(){
|
function updatesolves(){
|
||||||
$.get('/chals/solves', function (data) {
|
$.get(script_root + '/chals/solves', function (data) {
|
||||||
solves = $.parseJSON(JSON.stringify(data));
|
solves = $.parseJSON(JSON.stringify(data));
|
||||||
chals = Object.keys(solves);
|
chals = Object.keys(solves);
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ function updatesolves(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getsolves(id){
|
function getsolves(id){
|
||||||
$.get('/chal/'+id+'/solves', function (data) {
|
$.get(script_root + '/chal/'+id+'/solves', function (data) {
|
||||||
var teams = data['teams'];
|
var teams = data['teams'];
|
||||||
var box = $('#chal-solves-names');
|
var box = $('#chal-solves-names');
|
||||||
box.empty();
|
box.empty();
|
||||||
@@ -147,8 +147,7 @@ function getsolves(id){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadchals() {
|
function loadchals() {
|
||||||
|
$.get(script_root + "/chals", function (data) {
|
||||||
$.get("/chals", function (data) {
|
|
||||||
var categories = [];
|
var categories = [];
|
||||||
challenges = $.parseJSON(JSON.stringify(data));
|
challenges = $.parseJSON(JSON.stringify(data));
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
function updatescores () {
|
function updatescores () {
|
||||||
$.get('/scores', function( data ) {
|
$.get(script_root + '/scores', function( data ) {
|
||||||
teams = $.parseJSON(JSON.stringify(data));
|
teams = $.parseJSON(JSON.stringify(data));
|
||||||
$('#scoreboard > tbody').empty()
|
$('#scoreboard > tbody').empty()
|
||||||
for (var i = 0; i < teams['standings'].length; i++) {
|
for (var i = 0; i < teams['standings'].length; i++) {
|
||||||
@@ -23,7 +23,7 @@ function UTCtoDate(utc){
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
function scoregraph () {
|
function scoregraph () {
|
||||||
$.get('/top/10', function( data ) {
|
$.get(script_root + '/top/10', function( data ) {
|
||||||
var scores = $.parseJSON(JSON.stringify(data));
|
var scores = $.parseJSON(JSON.stringify(data));
|
||||||
scores = scores['scores'];
|
scores = scores['scores'];
|
||||||
if (Object.keys(scores).length == 0 ){
|
if (Object.keys(scores).length == 0 ){
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function scoregraph() {
|
|||||||
var times = []
|
var times = []
|
||||||
var scores = []
|
var scores = []
|
||||||
var teamname = $('#team-id').text()
|
var teamname = $('#team-id').text()
|
||||||
$.get('/solves/' + teamid(), function (data) {
|
$.get(script_root + '/solves/' + teamid(), function (data) {
|
||||||
var solves = $.parseJSON(JSON.stringify(data));
|
var solves = $.parseJSON(JSON.stringify(data));
|
||||||
solves = solves['solves'];
|
solves = solves['solves'];
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ function scoregraph() {
|
|||||||
|
|
||||||
function keys_percentage_graph() {
|
function keys_percentage_graph() {
|
||||||
// Solves and Fails pie chart
|
// Solves and Fails pie chart
|
||||||
$.get('/fails/' + teamid(), function (data) {
|
$.get(script_root + '/fails/' + teamid(), function (data) {
|
||||||
var res = $.parseJSON(JSON.stringify(data));
|
var res = $.parseJSON(JSON.stringify(data));
|
||||||
var solves = res['solves'];
|
var solves = res['solves'];
|
||||||
var fails = res['fails'];
|
var fails = res['fails'];
|
||||||
@@ -85,7 +85,7 @@ function keys_percentage_graph() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function category_breakdown_graph() {
|
function category_breakdown_graph() {
|
||||||
$.get('/solves/' + teamid(), function (data) {
|
$.get(script_root + '/solves/' + teamid(), function (data) {
|
||||||
var solves = $.parseJSON(JSON.stringify(data));
|
var solves = $.parseJSON(JSON.stringify(data));
|
||||||
solves = solves['solves'];
|
solves = solves['solves'];
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,18 @@
|
|||||||
<title>Admin Panel</title>
|
<title>Admin Panel</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<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="shortcut icon" href="{{ request.script_root }}/static/img/favicon.ico" type="image/x-icon">
|
||||||
<link rel="icon" href="/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="/static/css/vendor/bootstrap.min.css">
|
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="{{ request.script_root }}/static/css/style.css">
|
||||||
<link href='/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
<link href='{{ request.script_root }}/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
||||||
<link href='/static/css/vendor/raleway.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="/static/admin/css/style.css">
|
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/style.css">
|
||||||
<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>
|
||||||
{% block stylesheets %} {% endblock %}
|
{% block stylesheets %} {% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -27,20 +30,20 @@
|
|||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a href="/" class="navbar-brand">CTFd</a>
|
<a href="{{ request.script_root }}/" class="navbar-brand">CTFd</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
|
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
|
||||||
<ul class="nav navbar-nav navbar-nav-right">
|
<ul class="nav navbar-nav navbar-nav-right">
|
||||||
<li><a href="/admin/graphs">Graphs</a></li>
|
<li><a href="{{ request.script_root }}/admin/graphs">Graphs</a></li>
|
||||||
<li><a href="/admin/pages">Pages</a></li>
|
<li><a href="{{ request.script_root }}/admin/pages">Pages</a></li>
|
||||||
<li><a href="/admin/teams">Teams</a></li>
|
<li><a href="{{ request.script_root }}/admin/teams">Teams</a></li>
|
||||||
<li><a href="/admin/scoreboard">Scoreboard</a></li>
|
<li><a href="{{ request.script_root }}/admin/scoreboard">Scoreboard</a></li>
|
||||||
{% if can_create_container() %}
|
{% if can_create_container() %}
|
||||||
<li><a href="/admin/containers">Containers</a></li>
|
<li><a href="{{ request.script_root }}/admin/containers">Containers</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="/admin/chals">Challenges</a></li>
|
<li><a href="{{ request.script_root }}/admin/chals">Challenges</a></li>
|
||||||
<li><a href="/admin/statistics">Statistics</a></li>
|
<li><a href="{{ request.script_root }}/admin/statistics">Statistics</a></li>
|
||||||
<li><a href="/admin/config">Config</a></li>
|
<li><a href="{{ request.script_root }}/admin/config">Config</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,9 +53,9 @@
|
|||||||
{% block content %} {% endblock %}
|
{% block content %} {% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="/static/js/vendor/jquery.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/jquery.min.js"></script>
|
||||||
<script src="/static/js/vendor/marked.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/marked.min.js"></script>
|
||||||
<script src="/static/js/vendor/bootstrap.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/bootstrap.min.js"></script>
|
||||||
{% block scripts %} {% endblock %}
|
{% block scripts %} {% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<h3>New Challenge</h3>
|
<h3>New Challenge</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<input type="text" class="form-control" name="name" placeholder="Enter challenge name">
|
<input type="text" class="form-control" name="name" placeholder="Enter challenge name">
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
<h3 class="chal-title text-center"></h3>
|
<h3 class="chal-title text-center"></h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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 }}">
|
<input name='nonce' type='hidden' value="{{ nonce }}">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
<h3>Delete Challenge</h3>
|
<h3>Delete Challenge</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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="nonce" value="{{ nonce }}">
|
||||||
<input type="hidden" name="id" class="chal-id">
|
<input type="hidden" name="id" class="chal-id">
|
||||||
<div class="small-6 small-centered text-center columns">
|
<div class="small-6 small-centered text-center columns">
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
<h3>Keys</h3>
|
<h3>Keys</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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>
|
<a href="#" id="create-key" class="btn btn-primary" style="margin-bottom:15px;">New Key</a>
|
||||||
<input name='nonce' type='hidden' value="{{ nonce }}">
|
<input name='nonce' type='hidden' value="{{ nonce }}">
|
||||||
<input id="keys-chal" name='chal' type='hidden'>
|
<input id="keys-chal" name='chal' type='hidden'>
|
||||||
@@ -212,7 +212,7 @@
|
|||||||
<h3>Files</h3>
|
<h3>Files</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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 name='nonce' type='hidden' value="{{ nonce }}">
|
||||||
<input id="files-chal" name='chal' type='hidden'>
|
<input id="files-chal" name='chal' type='hidden'>
|
||||||
<input name='method' type='hidden' value='upload'>
|
<input name='method' type='hidden' value='upload'>
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/admin/js/multi-modal.js"></script>
|
<script src="{{ request.script_root }}/static/admin/js/multi-modal.js"></script>
|
||||||
<script src="/static/admin/js/chalboard.js"></script>
|
<script src="{{ request.script_root }}/static/admin/js/chalboard.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
aria-hidden="true">×</span></button>
|
aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="container-modal-label">Create Container</h4>
|
<h4 class="modal-title" id="container-modal-label">Create Container</h4>
|
||||||
</div>
|
</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="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for solve in solves %}
|
{% for solve in solves %}
|
||||||
<tr>
|
<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 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-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>
|
<td class="text-center">{{ solve.flag }}</td>
|
||||||
@@ -61,24 +61,24 @@
|
|||||||
{% if pages > 1 %}
|
{% if pages > 1 %}
|
||||||
<div class="text-center">Page
|
<div class="text-center">Page
|
||||||
<br>
|
<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) %}
|
{% for page in range(1, pages + 1) %}
|
||||||
{% if curr_page != page %}
|
{% if curr_page != page %}
|
||||||
<a href="/admin/correct_keys/{{ page }}">{{ page }}</a>
|
<a href="{{ request.script_root }}/admin/correct_keys/{{ page }}">{{ page }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{ page }}</b>
|
<b>{{ page }}</b>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if curr_page != pages %}<a href="/admin/correct_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
{% if curr_page != pages %}<a href="{{ request.script_root }}/admin/correct_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||||
<a href="">
|
<a href="{{ request.script_root }}">
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/admin/js/team.js"></script>
|
<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$('#delete-solve').click(function(e){
|
$('#delete-solve').click(function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
var modal = $('#confirm')
|
var modal = $('#confirm')
|
||||||
modal.find('#confirm-team-name').text(team_name)
|
modal.find('#confirm-team-name').text(team_name)
|
||||||
modal.find('#confirm-chal-name').text(chal_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');
|
$('#confirm').modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends "admin/base.html" %}
|
{% extends "admin/base.html" %}
|
||||||
|
|
||||||
{% block stylesheets %}
|
{% 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>
|
<style>
|
||||||
.row-fluid { margin: 25px; padding-bottom: 25px; }
|
.row-fluid { margin: 25px; padding-bottom: 25px; }
|
||||||
</style>
|
</style>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/vendor/codemirror.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/codemirror.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var editor = CodeMirror.fromTextArea(document.getElementById("admin-pages-editor"), {
|
var editor = CodeMirror.fromTextArea(document.getElementById("admin-pages-editor"), {
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('#page-edit').submit(function (e){
|
$('#page-edit').submit(function (e){
|
||||||
$(this).attr('action', '/admin/pages/'+$('#route').val());
|
$(this).attr('action', '{{ request.script_root }}/admin/pages/'+$('#route').val());
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
</style>
|
</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">
|
<script type="text/javascript">
|
||||||
// $.distint(array)
|
// $.distint(array)
|
||||||
// Unique elements in array
|
// Unique elements in array
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function solves_graph() {
|
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 solves = $.parseJSON(JSON.stringify(data));
|
||||||
var chals = [];
|
var chals = [];
|
||||||
var counts = [];
|
var counts = [];
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
function keys_percentage_graph(){
|
function keys_percentage_graph(){
|
||||||
// Solves and Fails pie chart
|
// 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 res = $.parseJSON(JSON.stringify(data));
|
||||||
var solves = res['solves'];
|
var solves = res['solves'];
|
||||||
var fails = res['fails'];
|
var fails = res['fails'];
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function category_breakdown_graph(){
|
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 = $.parseJSON(JSON.stringify(data));
|
||||||
res = res['categories']
|
res = res['categories']
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends "admin/base.html" %}
|
{% extends "admin/base.html" %}
|
||||||
|
|
||||||
{% block stylesheets %}
|
{% 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 %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3">
|
<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">
|
<table id="pages" class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for route in routes %}
|
{% for route in routes %}
|
||||||
<tr name="{{ route.route }}">
|
<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>
|
<td class="text-center"><i class="fa fa-times"></i></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/vendor/codemirror.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/codemirror.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var editor = CodeMirror.fromTextArea(document.getElementById("pages-editor"), {
|
var editor = CodeMirror.fromTextArea(document.getElementById("pages-editor"), {
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
@@ -85,7 +85,7 @@ function load_confirm_modal(route){
|
|||||||
var modal = $('#confirm')
|
var modal = $('#confirm')
|
||||||
modal.find('input[name=route]').val(route)
|
modal.find('input[name=route]').val(route)
|
||||||
modal.find('#confirm-route-name').text(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();
|
$('#confirm').modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,16 +17,16 @@
|
|||||||
{% for team in teams %}
|
{% for team in teams %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ loop.index }}</td>
|
<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>{{ team.score }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if not team.banned %}
|
{% 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>
|
<a onclick="$(this).parent().submit()">Ban</a>
|
||||||
<input type="hidden" value="{{ nonce }}" name="nonce">
|
<input type="hidden" value="{{ nonce }}" name="nonce">
|
||||||
</form>
|
</form>
|
||||||
{%else %}
|
{%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>
|
<a onclick="$(this).parent().submit()">Unban</a>
|
||||||
<input type="hidden" value="{{ nonce }}" name="nonce">
|
<input type="hidden" value="{{ nonce }}" name="nonce">
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
<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> <a href="wrong_keys/1">wrong 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="correct_keys/1">right 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>
|
<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].name }}</b> with {{ most_solved[1] }}</b> solves</h3>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if least_solved %}
|
{% if least_solved %}
|
||||||
<h3>Least solved: <b>{{ least_solved[0].name }}</b> with {{ least_solved[1] }}</b> solves</h3>
|
<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>
|
<h4 class="modal-title" id="create-award-label">Create Award</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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">
|
<div class="form-group">
|
||||||
<label for="award-name-input">Name</label>
|
<label for="award-name-input">Name</label>
|
||||||
<input type="text" class="form-control" id="award-name-input" name="name" placeholder="Enter award name">
|
<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>
|
<h3 id="confirm-title">Delete Key</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<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 }}">
|
<input id="nonce" type="hidden" name="nonce" value="{{ nonce }}">
|
||||||
<div class="small-6 small-centered text-center columns">
|
<div class="small-6 small-centered text-center columns">
|
||||||
<p id="confirm-description"></p>
|
<p id="confirm-description"></p>
|
||||||
@@ -104,8 +104,8 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for addr in addrs %}
|
{% for addr in addrs %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">{{ addr.ip|long2ip }}</td>
|
<td class="text-center">{{ addr[0]|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 solve-time"><script>document.write( moment({{ addr[1]|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -221,10 +221,10 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/vendor/moment.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/moment.min.js"></script>
|
||||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/admin/js/team.js"></script>
|
<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$('#delete-solve').click(function (e) {
|
$('#delete-solve').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -270,7 +270,7 @@
|
|||||||
description.find('#confirm-chal-name').text(chal_name);
|
description.find('#confirm-chal-name').text(chal_name);
|
||||||
description = description.html()
|
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') {
|
} else if (type == 'chal-wrong') {
|
||||||
var title = 'Delete Wrong Key';
|
var title = 'Delete Wrong Key';
|
||||||
var description = "<span>Are you sure you want to delete " +
|
var description = "<span>Are you sure you want to delete " +
|
||||||
@@ -285,12 +285,12 @@
|
|||||||
description.find('#confirm-chal-name').text(chal_name);
|
description.find('#confirm-chal-name').text(chal_name);
|
||||||
description = description.html()
|
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') {
|
} else if (type == 'award-row') {
|
||||||
var title = 'Delete Award';
|
var title = 'Delete Award';
|
||||||
var description = "<span>Are you sure you want to delete the " +
|
var description = "<span>Are you sure you want to delete the " +
|
||||||
"<strong>{0}</strong> award?</span>".format(chal_name);
|
"<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 = {
|
var msg = {
|
||||||
@@ -323,7 +323,7 @@
|
|||||||
description.find('#confirm-chal-name').text(chal_name);
|
description.find('#confirm-chal-name').text(chal_name);
|
||||||
description = description.html()
|
description = description.html()
|
||||||
|
|
||||||
var action = '/admin/solves/' + team + '/' + chal + '/solve';
|
var action = '{{request.script_root }}/admin/solves/' + team + '/' + chal + '/solve';
|
||||||
|
|
||||||
var msg = {
|
var msg = {
|
||||||
title : title,
|
title : title,
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ input[type="checkbox"] { margin: 0px !important; position: relative; top: 5px; }
|
|||||||
<h2 class="text-center">Edit User</h2>
|
<h2 class="text-center">Edit User</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body" style="padding:20px; height:525px;">
|
<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="nonce" value="{{ nonce }}">
|
||||||
<input type="hidden" name="id">
|
<input type="hidden" name="id">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -123,7 +123,7 @@ input[type="checkbox"] { margin: 0px !important; position: relative; top: 5px; }
|
|||||||
{% for team in teams %}
|
{% for team in teams %}
|
||||||
<tr name="{{ team.id }}">
|
<tr name="{{ team.id }}">
|
||||||
<td class="team-id">{{ team.id }}</td>
|
<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>
|
||||||
<td class="team-email">{{ team.email | truncate(32) }}</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 %}
|
<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 %}
|
{% if pages > 1 %}
|
||||||
<div class="text-center">Page
|
<div class="text-center">Page
|
||||||
<br>
|
<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) %}
|
{% for page in range(1, pages + 1) %}
|
||||||
{% if curr_page != page %}
|
{% if curr_page != page %}
|
||||||
<a href="/admin/teams/{{ page }}">{{ page }}</a>
|
<a href="{{ request.script_root }}/admin/teams/{{ page }}">{{ page }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{ page }}</b>
|
<b>{{ page }}</b>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% 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>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</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=website]').val(website)
|
||||||
modal_form.find('input[name=affiliation]').val(affiliation)
|
modal_form.find('input[name=affiliation]').val(affiliation)
|
||||||
modal_form.find('input[name=country]').val(country)
|
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");
|
$('#user').modal("show");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ $('.team-admin input').on('change', function(){
|
|||||||
var nonce = $('#nonce').val()
|
var nonce = $('#nonce').val()
|
||||||
console.log(admin)
|
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){
|
$('#send-user-email').click(function(e){
|
||||||
@@ -260,7 +260,7 @@ function load_confirm_modal(id, name){
|
|||||||
var modal = $('#confirm')
|
var modal = $('#confirm')
|
||||||
modal.find('input[name=id]').val(id)
|
modal.find('input[name=id]').val(id)
|
||||||
modal.find('#confirm-team-name').text(name)
|
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();
|
$('#confirm').modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ function load_email_modal(id){
|
|||||||
modal.find('textarea').val("")
|
modal.find('textarea').val("")
|
||||||
modal.find('input[name=id]').val(id)
|
modal.find('input[name=id]').val(id)
|
||||||
$('#email-user-errors').empty()
|
$('#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();
|
$('#email-user').modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for wrong_key in wrong_keys %}
|
{% for wrong_key in wrong_keys %}
|
||||||
<tr>
|
<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 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 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>
|
<td class="text-center">{{ wrong_key.flag }}</td>
|
||||||
@@ -68,24 +68,24 @@
|
|||||||
{% if pages > 1 %}
|
{% if pages > 1 %}
|
||||||
<div class="text-center">Page
|
<div class="text-center">Page
|
||||||
<br>
|
<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) %}
|
{% for page in range(1, pages + 1) %}
|
||||||
{% if curr_page != page %}
|
{% if curr_page != page %}
|
||||||
<a href="/admin/wrong_keys/{{ page }}">{{ page }}</a>
|
<a href="{{ request.script_root }}/admin/wrong_keys/{{ page }}">{{ page }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{ page }}</b>
|
<b>{{ page }}</b>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if curr_page != pages %}<a href="/admin/wrong_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
{% if curr_page != pages %}<a href="{{ request.script_root }}/admin/wrong_keys/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||||
<a href="">
|
<a href="{{ request.script_root }}">
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/admin/js/team.js"></script>
|
<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$('#delete-solve').click(function (e) {
|
$('#delete-solve').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
var modal = $('#confirm')
|
var modal = $('#confirm')
|
||||||
modal.find('#confirm-team-name').text(team_name);
|
modal.find('#confirm-team-name').text(team_name);
|
||||||
modal.find('#confirm-chal-name').text(chal_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');
|
$('#confirm').modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,19 @@
|
|||||||
<title>{{ ctf_name() }}</title>
|
<title>{{ ctf_name() }}</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<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="shortcut icon" href="{{ request.script_root }}/static/img/favicon.ico" type="image/x-icon">
|
||||||
<link rel="icon" href="/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="/static/css/vendor/bootstrap.min.css">
|
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
<link rel="stylesheet" href="{{ request.script_root }}/static/css/vendor/font-awesome/css/font-awesome.min.css" />
|
||||||
<link href='/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
<link href='{{ request.script_root }}/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
|
||||||
<link href='/static/css/vendor/raleway.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="/static/css/style.css">
|
<link rel="stylesheet" href="{{ request.script_root }}/static/css/style.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/user.css">
|
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/user.css">
|
||||||
{% block stylesheets %}{% endblock %}
|
{% 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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="body-container">
|
<div class="body-container">
|
||||||
@@ -25,31 +28,31 @@
|
|||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a href="/" class="navbar-brand">{{ ctf_name() }}</a>
|
<a href="{{ request.script_root }}/" class="navbar-brand">{{ ctf_name() }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
|
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
{% for page in pages() %}
|
{% 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 %}
|
{% endfor %}
|
||||||
<li><a href="/teams">Teams</a></li>
|
<li><a href="{{ request.script_root }}/teams">Teams</a></li>
|
||||||
<li><a href="/scoreboard">Scoreboard</a></li>
|
<li><a href="{{ request.script_root }}/scoreboard">Scoreboard</a></li>
|
||||||
<li><a href="/challenges">Challenges</a></li>
|
<li><a href="{{ request.script_root }}/challenges">Challenges</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
{% if username is defined %}
|
{% if username is defined %}
|
||||||
{% if admin %}
|
{% if admin %}
|
||||||
<li><a href="/admin">Admin</a></li>
|
<li><a href="{{ request.script_root }}/admin">Admin</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="/team/{{ id }}">Team</a></li>
|
<li><a href="{{ request.script_root }}/team/{{ id }}">Team</a></li>
|
||||||
<li><a href="/profile">Profile</a></li>
|
<li><a href="{{ request.script_root }}/profile">Profile</a></li>
|
||||||
<li><a href="/logout">Logout</a></li>
|
<li><a href="{{ request.script_root }}/logout">Logout</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if can_register() %}
|
{% 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>
|
<li><a style="padding-left:0px;padding-right:0px;">|</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="/login">Login</a></li>
|
<li><a href="{{ request.script_root }}/login">Login</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,9 +63,9 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<script src="/static/js/vendor/jquery.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/jquery.min.js"></script>
|
||||||
<script src="/static/js/vendor/marked.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/marked.min.js"></script>
|
||||||
<script src="/static/js/vendor/bootstrap.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/bootstrap.min.js"></script>
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/js/chalboard.js"></script>
|
<script src="{{ request.script_root }}/static/js/chalboard.js"></script>
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -44,6 +44,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="done-row row">
|
<div class="done-row row">
|
||||||
<div class="col-md-6" style="padding-left:0px">
|
<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>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button>
|
<button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button>
|
||||||
@@ -67,6 +67,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -132,5 +132,5 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
<script>
|
<script>
|
||||||
if (window.location.hash == "#frame"){
|
if (window.location.hash == "#frame"){
|
||||||
$('.top-bar').hide()
|
$('.top-bar').hide()
|
||||||
|
|||||||
@@ -55,5 +55,5 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for team in teams %}
|
{% 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 %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/js/scoreboard.js"></script>
|
<script src="{{ request.script_root }}/static/js/scoreboard.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -63,5 +63,5 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/style.js"></script>
|
<script src="{{ request.script_root }}/static/js/style.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for solve in solves %}
|
{% for solve in solves %}
|
||||||
<tr>
|
<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="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>
|
<td class="solve-time"><script>document.write( moment({{ solve.date|unix_time_millis }}).local().format('MMMM Do, h:mm:ss A'))</script></td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="/static/js/vendor/plotly.min.js"></script>
|
<script src="{{ request.script_root }}/static/js/vendor/plotly.min.js"></script>
|
||||||
<script src="/static/js/utils.js"></script>
|
<script src="{{ request.script_root }}/static/js/utils.js"></script>
|
||||||
<script src="/static/js/team.js"></script>
|
<script src="{{ request.script_root }}/static/js/team.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for team in teams %}
|
{% for team in teams %}
|
||||||
<tr>
|
<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>{% 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><span>{% if team.affiliation %}{{ team.affiliation }}{% endif %}</span></td>
|
||||||
<td class="hidden-xs"><span>{% if team.country %}{{ team.country }}{% endif %}</span></td>
|
<td class="hidden-xs"><span>{% if team.country %}{{ team.country }}{% endif %}</span></td>
|
||||||
@@ -33,16 +33,16 @@
|
|||||||
{% if team_pages > 1 %}
|
{% if team_pages > 1 %}
|
||||||
<div class="text-center">Page
|
<div class="text-center">Page
|
||||||
<br>
|
<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) %}
|
{% for page in range(1, team_pages + 1) %}
|
||||||
{% if curr_page != page %}
|
{% if curr_page != page %}
|
||||||
<a href="/teams/{{ page }}">{{ page }}</a>
|
<a href="{{ request.script_root }}/teams/{{ page }}">{{ page }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{page}}</b>
|
<b>{{page}}</b>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if curr_page != team_pages %}<a href="/teams/{{ curr_page+1 }}">>>></a>{% endif %}
|
{% if curr_page != team_pages %}<a href="{{ request.script_root }}/teams/{{ curr_page+1 }}">>>></a>{% endif %}
|
||||||
<a href="">
|
<a href="{{ request.script_root }}">
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ views = Blueprint('views', __name__)
|
|||||||
|
|
||||||
@views.before_request
|
@views.before_request
|
||||||
def redirect_setup():
|
def redirect_setup():
|
||||||
if request.path == "/static/css/style.css":
|
if request.path.startswith("/static"):
|
||||||
return
|
return
|
||||||
if not is_setup() and request.path != "/setup":
|
if not is_setup() and request.path != "/setup":
|
||||||
return redirect(url_for('views.setup'))
|
return redirect(url_for('views.setup'))
|
||||||
@@ -50,15 +50,15 @@ def setup():
|
|||||||
|
|
||||||
## Index page
|
## Index page
|
||||||
page = Pages('index', """<div class="container main-container">
|
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">
|
<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>
|
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>
|
</h3>
|
||||||
|
|
||||||
<h4 class="text-center">
|
<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>
|
</h4>
|
||||||
</div>""")
|
</div>""".format(request.script_root))
|
||||||
|
|
||||||
#max attempts per challenge
|
#max attempts per challenge
|
||||||
max_tries = set_config("max_tries",0)
|
max_tries = set_config("max_tries",0)
|
||||||
@@ -89,9 +89,9 @@ def setup():
|
|||||||
db.session.add(admin)
|
db.session.add(admin)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
app.setup = False
|
app.setup = False
|
||||||
return redirect('/')
|
return redirect(url_for('views.static_html'))
|
||||||
return render_template('setup.html', nonce=session.get('nonce'))
|
return render_template('setup.html', nonce=session.get('nonce'))
|
||||||
return redirect('/')
|
return redirect(url_for('views.static_html'))
|
||||||
|
|
||||||
|
|
||||||
# Custom CSS handler
|
# Custom CSS handler
|
||||||
|
|||||||
46
ctfd.ini
Normal file
46
ctfd.ini
Normal file
@@ -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
|
||||||
|
|
||||||
Reference in New Issue
Block a user