This commit is contained in:
2025-09-14 16:34:12 +02:00
parent 94f865665e
commit 5591a77870
3 changed files with 96 additions and 14 deletions

View File

@@ -27,6 +27,7 @@ from .auth import check_password, user_loader
from .forms import DeckForm, InfoBannerForm, LoginForm, PasswordForm from .forms import DeckForm, InfoBannerForm, LoginForm, PasswordForm
from .models import Deck, InfoBanner, Password, db from .models import Deck, InfoBanner, Password, db
from .utils import ( from .utils import (
create_token,
generate_password, generate_password,
generate_token, generate_token,
get_active_banner, get_active_banner,
@@ -49,18 +50,6 @@ def on_connect():
if flask_login.current_user.is_authenticated: if flask_login.current_user.is_authenticated:
join_room("instructor") join_room("instructor")
@main.before_request
def ensure_cookie():
token = get_token()
if token:
return
else:
token = generate_token()
resp = make_response(redirect(request.url))
resp.set_cookie('access_token', serialize_token(token), httponly=True)
return resp
@main.after_request @main.after_request
def inject_confused_button(response): def inject_confused_button(response):
if True: if True:
@@ -109,10 +98,48 @@ def inject_confused_button(response):
def index(): def index():
token = get_token() token = get_token()
if not token: if not token:
abort(500) return redirect(url_for("main.register"))
else: else:
return render_template('index.html', active_banner=get_active_banner(), decks=get_unlocked_decks(token), user_name=token.name) return render_template('index.html', active_banner=get_active_banner(), decks=get_unlocked_decks(token), user_name=token.name)
@main.route('/register', methods=['POST', 'GET'])
def register():
"""
Handles user registration.
GET: Renders the registration form.
POST: Processes the form submission.
"""
if request.method == 'POST':
# Get form data
user_name = request.form.get('username')
acknowledge = request.form.get('acknowledge')
# Simple validation
if not user_name:
flash('Username is required.', 'error')
return render_template('register.html')
if retrieve_token(user_name):
flash(f'The username "{user_name}" is already taken.', 'error')
return render_template('register.html')
if not acknowledge:
flash('You must acknowledge the important information to proceed.', 'error')
return render_template('register.html')
# If all validation passes, "register" the user
token = create_token(user_name)
print(f"User registered: {user_name}")
resp = make_response(redirect(url_for("main.index")))
resp.set_cookie('access_token', serialize_token(token), httponly=True)
flash(f'Registration successful for {user_name}!', 'success')
# Redirect to the login page after successful registration
return resp
# If GET request, render the form
return render_template('register.html')
@main.route('/login', methods=['POST', 'GET']) @main.route('/login', methods=['POST', 'GET'])
def login(): def login():

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register for Tutortool</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
@apply bg-background text-text font-sans;
background-color: #1a202c;
color: #a0aec0;
}
</style>
</head>
<body class="flex items-center justify-center min-h-screen">
<div class="bg-gray-800 p-8 rounded-lg shadow-lg max-w-md w-full border border-gray-700">
<div class="text-center mb-6">
<h1 class="text-3xl font-bold text-white mb-2">Create an Account</h1>
<p class="text-muted text-sm">Choose a username to get started.</p>
</div>
<form action="/register" method="POST" class="space-y-6">
<!-- Flask-WTF form fields will be injected here -->
<div class="mb-4">
<label for="username" class="block text-sm font-medium text-gray-400 mb-2">Username</label>
<input type="text" id="username" name="username" placeholder="Your unique username" required class="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div class="bg-gray-700 p-4 rounded-lg border border-gray-600 space-y-3">
<h3 class="text-sm font-semibold text-gray-200">Important Information</h3>
<p class="text-xs text-gray-400">
Your username is tied to the slides using a browser cookie. If you clear your cookies, you can regain access to your slides by logging in with the same username.
</p>
<div class="flex items-center">
<input type="checkbox" id="acknowledge" name="acknowledge" required class="h-4 w-4 text-blue-500 rounded border-gray-300 focus:ring-blue-500">
<label for="acknowledge" class="ml-2 block text-sm text-gray-400">
I understand and agree
</label>
</div>
</div>
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg transition-colors">
Register
</button>
</form>
<p class="text-center mt-4 text-sm">
Already have an account? <a href="/login" class="text-blue-400 hover:underline">Log In</a>
</p>
</div>
</body>
</html>

View File

@@ -28,7 +28,6 @@ def get_available_decks(app: Flask):
def generate_username() -> str: def generate_username() -> str:
return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=3, delimiter="-")) return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=3, delimiter="-"))
def generate_password() -> str: def generate_password() -> str:
return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=2, delimiter="-")) return cast(str, xkcd_password.generate_xkcdpassword(wordlist=words, numwords=2, delimiter="-"))
@@ -41,7 +40,9 @@ def generate_token() -> Token:
break break
else: else:
raise RuntimeError(f"Unique username could not be generated after {max_tries} tries") raise RuntimeError(f"Unique username could not be generated after {max_tries} tries")
return create_token(user_name)
def create_token(user_name : str) -> Token:
token = Token(user_name) token = Token(user_name)
db.session.add(token) db.session.add(token)
db.session.commit() db.session.commit()