from flask import Blueprint, render_template, request, redirect, url_for, flash from flask_login import login_user, logout_user, login_required, UserMixin, current_user from werkzeug.security import generate_password_hash, check_password_hash from extensions import db, login_manager, environment, htmx from jinja2_fragments import render_block auth = Blueprint('auth', __name__) class User(UserMixin): def __init__(self, id, username, password_hash, created_at, theme_preference='light'): self.id = id self.username = username self.password_hash = password_hash self.created_at = created_at self.theme_preference = theme_preference @staticmethod def get(user_id): user_data = db.get_user(int(user_id)) if user_data: return User(id=str(user_data['id']), username=user_data['username'], password_hash=user_data['password_hash'], created_at=user_data['created_at'], theme_preference=user_data.get('theme_preference', 'light')) return None @login_manager.user_loader def load_user(user_id): user_data = db.get_user(int(user_id)) if user_data: return User(id=str(user_data['id']), username=user_data['username'], password_hash=user_data['password_hash'], created_at=user_data['created_at'], theme_preference=user_data.get('theme_preference', 'light')) return None @auth.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': return render_template("login.html") username = request.form.get('username') password = request.form.get('password') if not username or not password: return render_template("login.html", error="Both username and password must be entered") user_data = db.get_user_by_username(username) if not user_data: return render_template("login.html", error="User does not exist") if not check_password_hash(user_data['password_hash'], password): return render_template("login.html", error="Invalid username or password") user = User(id=str(user_data['id']), username=user_data['username'], password_hash=user_data['password_hash'], created_at=user_data['created_at'], theme_preference=user_data.get('theme_preference', 'light')) login_user(user) next = request.args.get('next') return redirect(next or url_for('home.index')) @auth.route('/signup', methods=['GET', 'POST']) def signup(): if request.method == 'GET': return render_template("signup.html") username = request.form.get('username') password = request.form.get('password') if not username or not password: return render_template("signup.html", error="Both username and password must be entered") if len(username) < 10 or len(password) < 10: return render_template("signup.html", error="Both username and password must be at least 10 characters long") user = db.get_user_by_username(username) if user: return render_template("signup.html", error="User already exists") hashed_password = generate_password_hash(password) user_data = db.create_new_user(username, hashed_password) user = User(id=str(user_data['id']), username=user_data['username'], password_hash=user_data['password_hash'], created_at=user_data['created_at'], theme_preference=user_data.get('theme_preference', 'light')) login_user(user) return redirect(url_for('home.index')) @auth.route("/logout") @login_required def logout(): logout_user() return redirect(url_for('landing_page'))