Add household support: multi-household isolation, each with own admin and users, 38 tests
This commit is contained in:
@@ -3,7 +3,15 @@
|
||||
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
|
||||
from models import (
|
||||
get_user_by_username,
|
||||
create_user,
|
||||
create_household,
|
||||
get_household_by_name,
|
||||
get_household_by_id,
|
||||
get_all_households,
|
||||
count_household_users,
|
||||
)
|
||||
|
||||
auth_bp = Blueprint("auth", __name__)
|
||||
|
||||
@@ -23,10 +31,14 @@ def login():
|
||||
flash("Invalid username or password.", "error")
|
||||
return render_template("login.html")
|
||||
|
||||
household = get_household_by_id(user["household_id"])
|
||||
|
||||
session.clear()
|
||||
session["user_id"] = user["id"]
|
||||
session["username"] = user["username"]
|
||||
session["is_admin"] = bool(user["is_admin"])
|
||||
session["household_id"] = user["household_id"]
|
||||
session["household_name"] = household["name"] if household else "Unknown"
|
||||
return redirect(url_for("meals.dashboard"))
|
||||
|
||||
return render_template("login.html")
|
||||
@@ -34,10 +46,15 @@ def login():
|
||||
|
||||
@auth_bp.route("/register", methods=["GET", "POST"])
|
||||
def register():
|
||||
households = get_all_households()
|
||||
|
||||
if request.method == "POST":
|
||||
username = request.form.get("username", "").strip()
|
||||
password = request.form.get("password", "")
|
||||
confirm = request.form.get("confirm", "")
|
||||
household_action = request.form.get("household_action", "join") # "join" or "create"
|
||||
household_id = request.form.get("household_id", "").strip()
|
||||
new_household_name = request.form.get("new_household_name", "").strip()
|
||||
|
||||
errors = []
|
||||
if not username or len(username) < 2:
|
||||
@@ -49,20 +66,47 @@ def register():
|
||||
if get_user_by_username(username):
|
||||
errors.append("Username already taken.")
|
||||
|
||||
target_household_id = None
|
||||
|
||||
if household_action == "create":
|
||||
if not new_household_name:
|
||||
errors.append("Household name is required.")
|
||||
elif get_household_by_name(new_household_name):
|
||||
errors.append("A household with that name already exists.")
|
||||
else:
|
||||
household = create_household(new_household_name)
|
||||
target_household_id = household["id"]
|
||||
is_admin = True # First user in a new household is admin
|
||||
else:
|
||||
if not household_id:
|
||||
errors.append("Please select a household.")
|
||||
else:
|
||||
hh = get_household_by_id(int(household_id))
|
||||
if hh is None:
|
||||
errors.append("Selected household does not exist.")
|
||||
else:
|
||||
target_household_id = hh["id"]
|
||||
is_admin = False
|
||||
|
||||
if errors:
|
||||
for e in errors:
|
||||
flash(e, "error")
|
||||
return render_template("register.html")
|
||||
return render_template("register.html", households=households)
|
||||
|
||||
# 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)
|
||||
user = create_user(username, password_hash, target_household_id, is_admin=is_admin)
|
||||
|
||||
flash("Account created! Please log in.", "success")
|
||||
return redirect(url_for("auth.login"))
|
||||
session.clear()
|
||||
session["user_id"] = user["id"]
|
||||
session["username"] = user["username"]
|
||||
session["is_admin"] = bool(user["is_admin"])
|
||||
session["household_id"] = user["household_id"]
|
||||
session["household_name"] = get_household_by_id(target_household_id)["name"]
|
||||
|
||||
return render_template("register.html")
|
||||
flash("Account created! Welcome to your household.", "success")
|
||||
return redirect(url_for("meals.dashboard"))
|
||||
|
||||
return render_template("register.html", households=households)
|
||||
|
||||
|
||||
@auth_bp.route("/logout")
|
||||
|
||||
Reference in New Issue
Block a user