diff --git a/.gitignore b/.gitignore index 856d654..0e81128 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ dump.rdb /problems __pycache__ /static/* +/secrets diff --git a/app.py b/app.py index 5b4cd5b..e31fce5 100644 --- a/app.py +++ b/app.py @@ -8,6 +8,7 @@ from peewee import fn import config import utils import redis +import requests import logging logging.basicConfig(level=logging.DEBUG) @@ -37,10 +38,13 @@ def root(): @app.route('/scoreboard/') def scoreboard(): data = utils.get_complex("scoreboard") - if not data: + graphdata = utils.get_complex("graph") + if not data or not graphdata: data = utils.calculate_scores() - utils.set_complex("scoreboard", data, 10) - return render_template("scoreboard.html", data=data) + graphdata = utils.calculate_graph(data) + utils.set_complex("scoreboard", data, 120) + utils.set_complex("graph", graphdata, 120) + return render_template("scoreboard.html", data=data, graphdata=graphdata) @app.route('/login/', methods=["GET", "POST"]) def login(): @@ -64,12 +68,24 @@ def register(): if request.method == "GET": return render_template("register.html") elif request.method == "POST": + if "g-recaptcha-response" not in request.form: + flash("Please complete the CAPTCHA.") + return render_template("register.html") + + captcha_response = request.form["g-recaptcha-response"] + verify_data = dict(secret=config.secret.recaptcha_secret, response=captcha_response, remoteip=utils.get_ip()) + result = requests.post("https://www.google.com/recaptcha/api/siteverify", verify_data).json()["success"] + if not result: + flash("Invalid CAPTCHA response.") + return render_template("register.html") + team_name = request.form["team_name"] team_email = request.form["team_email"] team_elig = "team_eligibility" in request.form affiliation = request.form["affiliation"] team_key = utils.generate_team_key() team = Team.create(name=team_name, email=team_email, eligible=team_elig, affiliation=affiliation, key=team_key) + TeamAccess.create(team=team, ip=utils.get_ip(), time=datetime.now()) session["team_id"] = team.id flash("Team created.") return redirect(url_for('dashboard')) @@ -98,7 +114,12 @@ def dashboard(): team_solves = ChallengeSolve.select(ChallengeSolve, Challenge).join(Challenge).where(ChallengeSolve.team == g.team) team_adjustments = ScoreAdjustment.select().where(ScoreAdjustment.team == g.team) team_score = sum([i.challenge.points for i in team_solves] + [i.value for i in team_adjustments]) - return render_template("dashboard.html", team_solves=team_solves, team_adjustments=team_adjustments, team_score=team_score) + first_login = False + if g.team.first_login: + first_login = True + g.team.first_login = False + g.team.save() + return render_template("dashboard.html", team_solves=team_solves, team_adjustments=team_adjustments, team_score=team_score, first_login=first_login) elif request.method == "POST": team_name = request.form["team_name"] team_email = request.form["team_email"] diff --git a/config.py b/config.py index e2ed117..2f1fa87 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,15 @@ ctf_name = "TJCTF" eligibility = "In order to be eligible for prizes, all members of your team must be in high school, and you must not have more than four team members." +tagline = "a cybersecurity competition created by TJHSST students" competition_is_running = True cdn = True proxied_ip_header = "X-Forwarded-For" flag_rl = 10 +teams_on_graph = 10 + +# Don't touch these. Instead, copy secrets.example to secrets and edit that. +import yaml +from collections import namedtuple +with open("secrets") as f: + _secret = yaml.load(f) + secret = namedtuple('SecretsDict', _secret.keys())(**_secret) diff --git a/ctftool b/ctftool index dbb9757..dd444da 100755 --- a/ctftool +++ b/ctftool @@ -1,5 +1,6 @@ #!/usr/bin/python3 from database import * +from datetime import datetime, timedelta import sys import yaml import random @@ -26,7 +27,22 @@ elif operation == "gen-challenge": n = int(sys.argv[2]) for i in range(n): name = str(random.randint(0, 999999999)) - chal = Challenge.create(name="Challenge {}".format(name), category="Generated", description="Free flags. it's the number in the problem name lorem ipsum dolor sit whatever i don't even care", points=random.randint(50, 400), flag=name) + chal = Challenge.create(name="Challenge".format(name), category="Generated", description="Lorem ipsum, dolor sit amet. The flag is {}".format(name), points=random.randint(50, 400), flag=name) print("Challenge added with id {}".format(chal.id)) +elif operation == "gen-team": + n = int(sys.argv[2]) + chals = list(Challenge.select()) + ctz = datetime.now() + diff = timedelta(minutes=5) + for i in range(n): + name = "Team {}".format(i + 1) + t = Team.create(name=name, email="none@none.com", affiliation="Autogenerated", eligible=True, key="") + t.key = "autogen{}".format(t.id) + t.save() + print("Team added with id {}".format(t.id)) + for i in random.sample(chals, 5): + ChallengeSolve.create(team=t, challenge=i, time=ctz) + ctz = ctz + (diff * random.randint(-10, 10)) + # vim: syntax=python:ft=python diff --git a/database.py b/database.py index 9589658..6df0b9e 100644 --- a/database.py +++ b/database.py @@ -10,6 +10,7 @@ class Team(BaseModel): email = CharField() affiliation = CharField() eligible = BooleanField() + first_login = BooleanField(default=True) key = CharField() def solved(self, challenge): diff --git a/templates/base.html b/templates/base.html index 6b2213d..a829d06 100644 --- a/templates/base.html +++ b/templates/base.html @@ -3,6 +3,7 @@