diff --git a/app.py b/app.py index 500946e..87bb072 100644 --- a/app.py +++ b/app.py @@ -86,10 +86,22 @@ def register(): flash(message) return render_template("register.html") - team_name = request.form["team_name"] - team_email = request.form["team_email"] + team_name = request.form["team_name"].strip() + team_email = request.form["team_email"].strip() team_elig = "team_eligibility" in request.form - affiliation = request.form["affiliation"] + affiliation = request.form["affiliation"].strip() + + if len(team_name) > 50 or not team_name: + flash("You must have a team name!") + return render_template("register.html") + + if not (team_email and "." in team_email and "@" in team_email): + flash("You must have a valid team email!") + return render_template("register.html") + + if not affiliation: + affiliation = "No affiliation" + team_key = misc.generate_team_key() confirmation_key = misc.generate_confirmation_key() @@ -141,12 +153,22 @@ def dashboard(): flash("You're changing your information too fast!") return redirect(url_for('dashboard')) - g.redis.set("ul{}".format(session["team_id"]), str(datetime.now()), 120) - team_name = request.form["team_name"] - team_email = request.form["team_email"] - affiliation = request.form["affiliation"] + team_name = request.form["team_name"].strip() + team_email = request.form["team_email"].strip() + affiliation = request.form["affiliation"].strip() team_elig = "team_eligibility" in request.form + if len(team_name) > 50 or not team_name: + flash("You must have a team name!") + return render_template("dashboard.html") + + if not (team_email and "." in team_email and "@" in team_email): + flash("You must have a valid team email!") + return render_template("dashboard.html") + + if not affiliation: + affiliation = "No affiliation" + email_changed = (team_email != g.team.email) g.team.name = team_name @@ -155,6 +177,8 @@ def dashboard(): if not g.team.eligibility_locked: g.team.eligible = team_elig + g.redis.set("ul{}".format(session["team_id"]), str(datetime.now()), 120) + if email_changed: g.team.email_confirmation_key = misc.generate_confirmation_key() g.team.email_confirmed = False diff --git a/modules/admin.py b/modules/admin.py index eeeca83..db4b9ab 100644 --- a/modules/admin.py +++ b/modules/admin.py @@ -3,7 +3,7 @@ from database import AdminUser, Team, Challenge, ChallengeSolve, ChallengeFailur import utils import utils.admin import utils.scoreboard -from utils.decorators import admin_required +from utils.decorators import admin_required, csrf_check from utils.notification import make_link from datetime import datetime admin = Blueprint("admin", "admin", url_prefix="/admin") @@ -87,6 +87,23 @@ def admin_show_team(tid): team = Team.get(Team.id == tid) return render_template("admin/team.html", team=team) +@admin.route("/team///impersonate/") +@csrf_check +@admin_required +def admin_impersonate_team(tid): + session["team_id"] = tid + return redirect(url_for("scoreboard")) + +@admin.route("/team///toggle_eligibility_lock/") +@csrf_check +@admin_required +def admin_toggle_eligibility_lock(tid): + team = Team.get(Team.id == tid) + team.eligibility_locked = not team.eligibility_locked + team.save() + flash("Eligibility lock set to {}".format(team.eligibility_locked)) + return redirect(url_for(".admin_show_team", tid=tid)) + @admin.route("/logout/") def admin_logout(): del session["admin"] diff --git a/templates/admin/team.html b/templates/admin/team.html index c48ebfa..af8403e 100644 --- a/templates/admin/team.html +++ b/templates/admin/team.html @@ -1,11 +1,12 @@ {% extends "admin/base.html" %} {% block content %}

{{ team.name }}

-

This team is {{ "eligible" if team.eligible else "not eligible" }}.

+Impersonate team
+

This team is {{ "eligible" if team.eligible else "not eligible" }}. Eligibility is {{ "locked" if team.eligibility_locked else "unlocked" }} (toggle).

This team's affiliation is {{ team.affiliation }}

Email

This team's email is {{ team.email }} ({{ "confirmed" if team.email_confirmed else "unconfirmed" }}).

-{% if not team.email_confirmed or 1 %} +{% if not team.email_confirmed %}

This team's confirmation key is {{ team.email_confirmation_key }}. {% endif %} {% endblock %} diff --git a/templates/dashboard.html b/templates/dashboard.html index 5164721..0e4c67c 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -75,7 +75,7 @@

- +
diff --git a/templates/register.html b/templates/register.html index 3f4c970..1748504 100644 --- a/templates/register.html +++ b/templates/register.html @@ -11,7 +11,7 @@ contain a "team key", which is used to log in.

team members.

- +
@@ -19,7 +19,7 @@ team members.

- +

{{ config.eligibility }}

diff --git a/utils/decorators.py b/utils/decorators.py index e4d89d0..352b6d9 100644 --- a/utils/decorators.py +++ b/utils/decorators.py @@ -1,5 +1,5 @@ import config -from flask import session, redirect, url_for, flash, g +from flask import session, redirect, url_for, flash, g, abort from functools import wraps def login_required(f): @@ -40,3 +40,19 @@ def admin_required(f): return redirect(url_for("admin.admin_login")) return f(*args, **kwargs) return decorated + +def csrf_check(f): + @wraps(f) + def decorated(*args, **kwargs): + if "csrf" not in kwargs: + abort(403) + return + + if kwargs["csrf"] != session["_csrf_token"]: + abort(403) + return + + del kwargs["csrf"] + + return f(*args, **kwargs) + return decorated