85 lines
3.4 KiB
Python
85 lines
3.4 KiB
Python
from flask import Blueprint, render_template, request, flash, redirect, url_for, current_app
|
|
from flask_mail import Message
|
|
from itsdangerous import URLSafeTimedSerializer, SignatureExpired, BadSignature
|
|
from app.extensions import db, mail
|
|
from app.models import Participant
|
|
|
|
bp = Blueprint('main', __name__)
|
|
|
|
def get_confirmed_count():
|
|
return Participant.query.filter_by(confirmed=True).count()
|
|
|
|
def send_verification_email(user_email):
|
|
s = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
|
|
token = s.dumps(user_email, salt='email-confirm-h4tum-ctf-2025')
|
|
link = url_for('main.verify_email', token=token, _external=True)
|
|
|
|
#msg = Message('Verify your CTF Registration', recipients=["fdohq9ipugtc@mockmail.io"])
|
|
#msg.body = f'Click here to confirm your spot: {link}\nThanks for registering {user_email}'
|
|
print(link)
|
|
|
|
@bp.route('/', methods=['GET', 'POST'])
|
|
def index():
|
|
confirmed_count = get_confirmed_count()
|
|
max_spots = current_app.config['MAX_SPOTS']
|
|
spots_left = max_spots - confirmed_count
|
|
|
|
if request.method == 'POST':
|
|
name = request.form['name']
|
|
email = request.form['email'].lower().strip()
|
|
looking_for_team = True if request.form.get('looking_for_team') else False
|
|
|
|
tum_domain = current_app.config['TUM_DOMAIN']
|
|
if not email.endswith(f"@{tum_domain}"):
|
|
flash(f"Error: You must use a @{tum_domain} email address.", "error")
|
|
return redirect(url_for('main.index'))
|
|
|
|
if confirmed_count >= max_spots:
|
|
flash("Sorry, the event is full!", "error")
|
|
return redirect(url_for('main.index'))
|
|
|
|
existing_user = Participant.query.filter_by(email=email).first()
|
|
if existing_user:
|
|
if existing_user.confirmed:
|
|
flash("You are already registered and confirmed!", "info")
|
|
else:
|
|
flash("Confirmation email resent. Please check your inbox.", "info")
|
|
send_verification_email(email)
|
|
return redirect(url_for('main.index'))
|
|
|
|
new_user = Participant(name=name, email=email, looking_for_team=looking_for_team)
|
|
db.session.add(new_user)
|
|
db.session.commit()
|
|
|
|
send_verification_email(email)
|
|
flash("Registration started! Check your email to confirm your spot.", "success")
|
|
return redirect(url_for('main.index'))
|
|
|
|
return render_template('index.html', spots_left=spots_left)
|
|
|
|
@bp.route('/verify/<token>')
|
|
def verify_email(token):
|
|
s = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
|
|
try:
|
|
email = s.loads(token, salt='email-confirm-h4tum-ctf-2025', max_age=3600)
|
|
except SignatureExpired:
|
|
return '<h1>Token expired. Please register again.</h1>'
|
|
except BadSignature:
|
|
return '<h1>Invalid token.</h1>'
|
|
|
|
user = Participant.query.filter_by(email=email).first_or_404()
|
|
|
|
if get_confirmed_count() >= current_app.config['MAX_SPOTS']:
|
|
return '<h1>Sorry! The event filled up while you were verifying.</h1>'
|
|
|
|
user.confirmed = True
|
|
db.session.commit()
|
|
|
|
discord_link = current_app.config['DISCORD_LINK']
|
|
discord_token = user.discord_token
|
|
msg = "You are confirmed!"
|
|
if user.looking_for_team:
|
|
msg += " Since you need a team, please join the #looking-for-group channel."
|
|
|
|
return render_template('success.html', message=msg, discord_link=discord_link, discord_token=discord_token)
|