72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
"""Authentication blueprint — login, register, logout."""
|
|
|
|
from flask import Blueprint, request, render_template, redirect, url_for, session, flash
|
|
from werkzeug.security import generate_password_hash, check_password_hash
|
|
|
|
from models import get_user_by_username, create_user, count_users
|
|
|
|
auth_bp = Blueprint("auth", __name__)
|
|
|
|
|
|
@auth_bp.route("/login", methods=["GET", "POST"])
|
|
def login():
|
|
if request.method == "POST":
|
|
username = request.form.get("username", "").strip()
|
|
password = request.form.get("password", "")
|
|
|
|
if not username or not password:
|
|
flash("Username and password are required.", "error")
|
|
return render_template("login.html")
|
|
|
|
user = get_user_by_username(username)
|
|
if user is None or not check_password_hash(user["password_hash"], password):
|
|
flash("Invalid username or password.", "error")
|
|
return render_template("login.html")
|
|
|
|
session.clear()
|
|
session["user_id"] = user["id"]
|
|
session["username"] = user["username"]
|
|
session["is_admin"] = bool(user["is_admin"])
|
|
return redirect(url_for("meals.dashboard"))
|
|
|
|
return render_template("login.html")
|
|
|
|
|
|
@auth_bp.route("/register", methods=["GET", "POST"])
|
|
def register():
|
|
if request.method == "POST":
|
|
username = request.form.get("username", "").strip()
|
|
password = request.form.get("password", "")
|
|
confirm = request.form.get("confirm", "")
|
|
|
|
errors = []
|
|
if not username or len(username) < 2:
|
|
errors.append("Username must be at least 2 characters.")
|
|
if not password or len(password) < 4:
|
|
errors.append("Password must be at least 4 characters.")
|
|
if password != confirm:
|
|
errors.append("Passwords do not match.")
|
|
if get_user_by_username(username):
|
|
errors.append("Username already taken.")
|
|
|
|
if errors:
|
|
for e in errors:
|
|
flash(e, "error")
|
|
return render_template("register.html")
|
|
|
|
# First user to register becomes admin
|
|
is_admin = count_users() == 0
|
|
password_hash = generate_password_hash(password)
|
|
create_user(username, password_hash, is_admin=is_admin)
|
|
|
|
flash("Account created! Please log in.", "success")
|
|
return redirect(url_for("auth.login"))
|
|
|
|
return render_template("register.html")
|
|
|
|
|
|
@auth_bp.route("/logout")
|
|
def logout():
|
|
session.clear()
|
|
return redirect(url_for("auth.login"))
|