finished auth overhaul and started tenants

This commit is contained in:
2025-10-14 01:30:22 +02:00
parent 5591a77870
commit 02fc60151f
10 changed files with 215 additions and 86 deletions

View File

@@ -12,7 +12,6 @@ from flask import (
abort,
current_app,
flash,
jsonify,
make_response,
redirect,
render_template,
@@ -29,8 +28,8 @@ from .models import Deck, InfoBanner, Password, db
from .utils import (
create_token,
generate_password,
generate_token,
get_active_banner,
get_all_courses,
get_available_decks,
get_token,
get_unlocked_decks,
@@ -38,6 +37,7 @@ from .utils import (
retrieve_token,
serialize_token,
update_token,
get_course
)
@@ -98,9 +98,39 @@ def inject_confused_button(response):
def index():
token = get_token()
if not token:
return redirect(url_for("main.register"))
return redirect(url_for("main.set_token"))
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, active_course_id=token.active_course_id, courses=get_all_courses())
@main.route('/set_token', methods=['POST', 'GET'])
def set_token():
"""
Handles.
GET: Renders the registration form.
POST: Processes the form submission.
"""
if request.method == 'POST':
# Get form data
user_name = request.form.get('username')
# Simple validation
if not user_name:
flash('Username is required.', 'error')
return render_template('set_token.html')
token = retrieve_token(user_name)
if not token:
flash(f'The username "{user_name}" does not exist.', 'error')
return render_template('set_token.html')
resp = make_response(redirect(url_for("main.index")))
resp.set_cookie('access_token', serialize_token(token), httponly=True)
return resp
# If GET request, render the form
return render_template('set_token.html')
@main.route('/register', methods=['POST', 'GET'])
def register():
@@ -134,15 +164,34 @@ def register():
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'])
def login():
@main.route('/logout', methods=['POST'])
def logout():
resp = make_response(redirect(url_for('main.index'))) # Redirect to a safe page, e.g., index or login
resp.set_cookie('access_token', '', expires=0) # Clears the cookie
return resp
@main.route('/switch_course/<new_course>', methods=['POST'])
def switch_course(new_course: int):
token = get_token()
if not token:
return redirect(url_for('main.set_token'))
switched = get_course(new_course)
if switched:
token.active_course = switched
db.session.commit()
return redirect(url_for("main.index"))
@main.route('/admin/login', methods=['POST', 'GET'])
def admin_login():
form = LoginForm()
if form.validate_on_submit():
assert isinstance(form.user_name.data, str)
@@ -152,8 +201,6 @@ def login():
user = user_loader(user_name)
if user and check_password(user, password):
flask_login.login_user(user)
flash('Login successful!', 'success')
next = request.args.get('next')
if next is None:
return redirect(url_for('main.index'))
@@ -164,7 +211,7 @@ def login():
return redirect(next)
else:
flash('Incorrect username or password. Please try again.', 'error')
return render_template("login.html", form=form)
return render_template("admin_login.html", form=form)
@main.route('/access', methods=['POST'])
@@ -174,7 +221,7 @@ def access():
token = get_token()
if password is not None and not password.is_expired():
update_token(password.decks)
return redirect('/')
return redirect(url_for('main.index'))
return render_template('index.html', error="Invalid password.", decks=get_unlocked_decks(token))
@@ -185,14 +232,13 @@ def access_link(access_code: str):
token = get_token()
if password is not None and not password.is_expired():
update_token(password.decks)
return redirect('/')
return redirect(url_for('main.index'))
return render_template('index.html', error="Invalid password.", decks=get_unlocked_decks(token))
@main.route('/confused', methods=['POST'])
def confused():
socketio.emit(
"confused",
{
@@ -202,18 +248,6 @@ def confused():
)
return ("", 204)
@main.route('/retrieve-token', methods=['POST'])
def set_username_token():
new_username : str = request.form.get("user_name", "").strip()
resp = make_response(redirect('/'))
if new_username:
token = retrieve_token(new_username)
if token:
resp.set_cookie('access_token', serialize_token(token), httponly=True)
return resp
@main.route('/slides/<deck>/')
@main.route('/slides/<deck>/<path:path>')
def serve_deck(deck, path='index.html'):
@@ -221,7 +255,7 @@ def serve_deck(deck, path='index.html'):
abort(404)
if not is_deck_unlocked(deck):
return redirect('/')
return redirect(url_for('main.index'))
slides_dir = current_app.config['SLIDES_DIR']
deck_path = os.path.join(slides_dir, deck)