parent
a36184f9dc
commit
d4dd155ed6
38
app.py
38
app.py
|
@ -86,10 +86,22 @@ def register():
|
||||||
flash(message)
|
flash(message)
|
||||||
return render_template("register.html")
|
return render_template("register.html")
|
||||||
|
|
||||||
team_name = request.form["team_name"]
|
team_name = request.form["team_name"].strip()
|
||||||
team_email = request.form["team_email"]
|
team_email = request.form["team_email"].strip()
|
||||||
team_elig = "team_eligibility" in request.form
|
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()
|
team_key = misc.generate_team_key()
|
||||||
confirmation_key = misc.generate_confirmation_key()
|
confirmation_key = misc.generate_confirmation_key()
|
||||||
|
|
||||||
|
@ -141,12 +153,22 @@ def dashboard():
|
||||||
flash("You're changing your information too fast!")
|
flash("You're changing your information too fast!")
|
||||||
return redirect(url_for('dashboard'))
|
return redirect(url_for('dashboard'))
|
||||||
|
|
||||||
g.redis.set("ul{}".format(session["team_id"]), str(datetime.now()), 120)
|
team_name = request.form["team_name"].strip()
|
||||||
team_name = request.form["team_name"]
|
team_email = request.form["team_email"].strip()
|
||||||
team_email = request.form["team_email"]
|
affiliation = request.form["affiliation"].strip()
|
||||||
affiliation = request.form["affiliation"]
|
|
||||||
team_elig = "team_eligibility" in request.form
|
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)
|
email_changed = (team_email != g.team.email)
|
||||||
|
|
||||||
g.team.name = team_name
|
g.team.name = team_name
|
||||||
|
@ -155,6 +177,8 @@ def dashboard():
|
||||||
if not g.team.eligibility_locked:
|
if not g.team.eligibility_locked:
|
||||||
g.team.eligible = team_elig
|
g.team.eligible = team_elig
|
||||||
|
|
||||||
|
g.redis.set("ul{}".format(session["team_id"]), str(datetime.now()), 120)
|
||||||
|
|
||||||
if email_changed:
|
if email_changed:
|
||||||
g.team.email_confirmation_key = misc.generate_confirmation_key()
|
g.team.email_confirmation_key = misc.generate_confirmation_key()
|
||||||
g.team.email_confirmed = False
|
g.team.email_confirmed = False
|
||||||
|
|
|
@ -3,7 +3,7 @@ from database import AdminUser, Team, Challenge, ChallengeSolve, ChallengeFailur
|
||||||
import utils
|
import utils
|
||||||
import utils.admin
|
import utils.admin
|
||||||
import utils.scoreboard
|
import utils.scoreboard
|
||||||
from utils.decorators import admin_required
|
from utils.decorators import admin_required, csrf_check
|
||||||
from utils.notification import make_link
|
from utils.notification import make_link
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
admin = Blueprint("admin", "admin", url_prefix="/admin")
|
admin = Blueprint("admin", "admin", url_prefix="/admin")
|
||||||
|
@ -87,6 +87,23 @@ def admin_show_team(tid):
|
||||||
team = Team.get(Team.id == tid)
|
team = Team.get(Team.id == tid)
|
||||||
return render_template("admin/team.html", team=team)
|
return render_template("admin/team.html", team=team)
|
||||||
|
|
||||||
|
@admin.route("/team/<int:tid>/<csrf>/impersonate/")
|
||||||
|
@csrf_check
|
||||||
|
@admin_required
|
||||||
|
def admin_impersonate_team(tid):
|
||||||
|
session["team_id"] = tid
|
||||||
|
return redirect(url_for("scoreboard"))
|
||||||
|
|
||||||
|
@admin.route("/team/<int:tid>/<csrf>/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/")
|
@admin.route("/logout/")
|
||||||
def admin_logout():
|
def admin_logout():
|
||||||
del session["admin"]
|
del session["admin"]
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
{% extends "admin/base.html" %}
|
{% extends "admin/base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{ team.name }}</h2>
|
<h2>{{ team.name }}</h2>
|
||||||
<p>This team is <strong>{{ "eligible" if team.eligible else "not eligible" }}</strong>.</p>
|
<a href="{{ url_for('admin.admin_impersonate_team', tid=team.id, csrf=csrf_token()) }}">Impersonate team</a><br />
|
||||||
|
<p>This team is <strong>{{ "eligible" if team.eligible else "not eligible" }}</strong>. Eligibility is <strong>{{ "locked" if team.eligibility_locked else "unlocked" }}</strong> (<a href="{{ url_for('admin.admin_toggle_eligibility_lock', tid=team.id, csrf=csrf_token()) }}">toggle</a>).</p>
|
||||||
<p>This team's affiliation is <strong>{{ team.affiliation }}</strong></p>
|
<p>This team's affiliation is <strong>{{ team.affiliation }}</strong></p>
|
||||||
<h3>Email</h3>
|
<h3>Email</h3>
|
||||||
<p>This team's email is <strong>{{ team.email }} ({{ "confirmed" if team.email_confirmed else "unconfirmed" }})</strong>.</p>
|
<p>This team's email is <strong>{{ team.email }} ({{ "confirmed" if team.email_confirmed else "unconfirmed" }})</strong>.</p>
|
||||||
{% if not team.email_confirmed or 1 %}
|
{% if not team.email_confirmed %}
|
||||||
<p>This team's confirmation key is <code>{{ team.email_confirmation_key }}</code>.
|
<p>This team's confirmation key is <code>{{ team.email_confirmation_key }}</code>.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<label for="team-name">Team Name</label>
|
<label for="team-name">Team Name</label>
|
||||||
<input required id="team-name" name="team_name" type="text" value="{{ team.name }}" />
|
<input required maxlength="50" id="team-name" name="team_name" type="text" value="{{ team.name }}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<label for="team-email">Team Email</label>
|
<label for="team-email">Team Email</label>
|
||||||
|
|
|
@ -11,7 +11,7 @@ contain a "team key", which is used to log in.</p>
|
||||||
team members.</strong></p>
|
team members.</strong></p>
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input required id="team-name" name="team_name" type="text" />
|
<input required maxlength="50" id="team-name" name="team_name" type="text" />
|
||||||
<label for="team-name">Team Name</label>
|
<label for="team-name">Team Name</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
|
@ -19,7 +19,7 @@ team members.</strong></p>
|
||||||
<label for="team-email">Team Email</label>
|
<label for="team-email">Team Email</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input required id="affiliation" name="affiliation" type="text" />
|
<input id="affiliation" name="affiliation" type="text" />
|
||||||
<label for="affiliation">Affiliation</label>
|
<label for="affiliation">Affiliation</label>
|
||||||
</div>
|
</div>
|
||||||
<p>{{ config.eligibility }}</p>
|
<p>{{ config.eligibility }}</p>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import config
|
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
|
from functools import wraps
|
||||||
|
|
||||||
def login_required(f):
|
def login_required(f):
|
||||||
|
@ -40,3 +40,19 @@ def admin_required(f):
|
||||||
return redirect(url_for("admin.admin_login"))
|
return redirect(url_for("admin.admin_login"))
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
return decorated
|
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
|
||||||
|
|
Loading…
Reference in New Issue