This commit is contained in:
2026-01-12 22:43:52 +01:00
parent 9f7683caa9
commit bfee5d1bb6
3 changed files with 64 additions and 5 deletions

View File

@@ -1,6 +1,6 @@
from flask import Blueprint, render_template, request, flash, redirect, url_for, current_app from flask import Blueprint, render_template, request, flash, redirect, url_for, current_app
from flask_mail import Message from flask_mail import Message
from itsdangerous import URLSafeTimedSerializer, SignatureExpired, BadSignature from itsdangerous import URLSafeTimedSerializer, SignatureExpired, BadSignature, exc
from app.extensions import db, mail, limiter from app.extensions import db, mail, limiter
from app.models import Participant from app.models import Participant
import traceback import traceback
@@ -20,12 +20,14 @@ def add_user(name, email, looking_for_team, on_waitlist = False):
def send_verification_email(user): def send_verification_email(user):
s = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) s = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
token = s.dumps(user.email, salt='email-confirm-h4tum-ctf-2025') register_token = s.dumps(user.email, salt='email-confirm-h4tum-ctf-2025')
link = url_for('main.verify_email', token=token, _external=True) remove_token = s.dumps(user.email, salt='email-remove-h4tum-ctf-2026')
register_link = url_for('main.verify_email', token=register_token, _external=True)
remove_link = url_for('main.remove_registration', token=remove_token, _external=True)
logo = url_for('static', filename='h4tum_white.png', _external=True) logo = url_for('static', filename='h4tum_white.png', _external=True)
msg = Message('Verify your CTF Registration', recipients=[user.email]) msg = Message('Verify your CTF Registration', recipients=[user.email])
msg.html = render_template("email.html", user_name=user.name, link=link, logo_url=logo) msg.html = render_template("email.html", user_name=user.name, register_link=register_link, remove_link=remove_link, logo_url=logo)
mail.send(msg) mail.send(msg)
user.num_emails_sent += 1 user.num_emails_sent += 1
db.session.commit() db.session.commit()
@@ -111,6 +113,31 @@ def verify_email(token):
return render_template('success.html', message=msg, discord_link=discord_link, discord_token=discord_token) return render_template('success.html', message=msg, discord_link=discord_link, discord_token=discord_token)
@bp.route('/remove/<token>')
@limiter.limit("5 per hour")
def remove_registration(token):
s = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
try:
email = s.loads(token, salt='email-remove-h4tum-ctf-2026', max_age=1209600)
except SignatureExpired:
return render_template("error.html", error_message="Token expired. Please register again.")
except BadSignature:
return render_template("error.html", error_message="Invalid token.")
user = Participant.query.filter_by(email=email).first_or_404()
if not user:
return render_template("error.html", error_message="No user found.")
try:
db.session.delete(user)
db.session.commit()
return render_template("deregistered.html", message="Sad to see you go. Comeback next time :D")
except:
db.session.rollback()
return render_template("error.html", error_message="Removing user did not work")
@bp.route('/dsgvo') @bp.route('/dsgvo')
@limiter.exempt @limiter.exempt
def dsgvo(): def dsgvo():

View File

@@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block content %}
<style>
.container {
text-align: center;
}
</style>
<div class="container">
<h1>> Remove user</h1>
<h1 style="color:#ffffff;">{{ message }}</h1>
</div>
{% endblock %}

View File

@@ -30,7 +30,7 @@
<table border="0" cellspacing="0" cellpadding="0" align="center"> <table border="0" cellspacing="0" cellpadding="0" align="center">
<tr> <tr>
<td align="center" bgcolor="#00ff00" style="padding: 15px 25px;"> <td align="center" bgcolor="#00ff00" style="padding: 15px 25px;">
<a href="{{ link }}" target="_blank" style="font-size: 18px; font-weight: bold; color: #000000; text-decoration: none; display: inline-block;"> <a href="{{ register_link }}" target="_blank" style="font-size: 18px; font-weight: bold; color: #000000; text-decoration: none; display: inline-block;">
CONFIRM MY SPOT CONFIRM MY SPOT
</a> </a>
</td> </td>
@@ -39,6 +39,24 @@
</td> </td>
</tr> </tr>
<tr>
<td align="center" style="padding-bottom: 30px; font-size: 16px; line-height: 1.5; text-align: center;">
If you can not attend please deregister using the following link
</td>
</tr>
<tr>
<td align="center" style="padding-bottom: 30px;">
<table border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td align="center" bgcolor="#D32F2F" style="padding: 15px 25px;">
<a href="{{ remove_link }}" target="_blank" style="font-size: 18px; font-weight: bold; color: #000000; text-decoration: none; display: inline-block;">
DEREGISTER
</a>
</td>
</tr>
</table>
</td>
</tr>
<tr> <tr>
<td align="center" style="padding-top: 20px; border-top: 1px solid #333333; font-size: 12px; color: #888888; text-align: center;"> <td align="center" style="padding-top: 20px; border-top: 1px solid #333333; font-size: 12px; color: #888888; text-align: center;">
If you didn't request this, you can safely ignore this email. If you didn't request this, you can safely ignore this email.