fix(auth): role-aware post-login landing to avoid 403 for non-MeasurementTec
Login always redirected to measure.select_recipe, which is gated by
@role_required("MeasurementTec"). A Maker-only (or Metrologist-only) user
was therefore bounced straight to a 403 right after a successful login.
Add _post_login_landing() which selects the landing endpoint from the user's
roles (MeasurementTec -> measure, Maker -> maker recipes, Metrologist ->
statistics, admin -> users, else profile). Used for both fresh login and the
already-authenticated short-circuit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,15 +39,32 @@ def role_required(*roles):
|
||||
return decorator
|
||||
|
||||
|
||||
def _post_login_landing():
|
||||
"""Pick the landing endpoint based on the logged-in user's roles.
|
||||
|
||||
A Maker-only user must not be bounced to /measure (MeasurementTec-only),
|
||||
which would raise a 403 right after login. Order of preference follows the
|
||||
primary operator flow first, then editing, analysis, admin.
|
||||
"""
|
||||
user = session.get("user", {})
|
||||
roles = user.get("roles", [])
|
||||
if "MeasurementTec" in roles:
|
||||
return url_for("measure.select_recipe")
|
||||
if "Maker" in roles:
|
||||
return url_for("maker.recipe_list")
|
||||
if "Metrologist" in roles:
|
||||
return url_for("statistics.dashboard")
|
||||
if user.get("is_admin"):
|
||||
return url_for("admin.user_list")
|
||||
return url_for("auth.profile")
|
||||
|
||||
|
||||
@auth_bp.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
"""Login page and form handler."""
|
||||
# Se già loggato, redirect a home
|
||||
# Se già loggato, redirect alla home in base al ruolo
|
||||
if session.get("api_key"):
|
||||
try:
|
||||
return redirect(url_for("measure.select_recipe"))
|
||||
except Exception:
|
||||
return redirect(url_for("auth.profile"))
|
||||
return redirect(_post_login_landing())
|
||||
|
||||
if request.method == "POST":
|
||||
username = request.form.get("username", "").strip()
|
||||
@@ -91,11 +108,8 @@ def login():
|
||||
|
||||
flash(_("Benvenuto, %(name)s!", name=user.get("display_name", username)), "success")
|
||||
|
||||
# Redirect dopo login
|
||||
try:
|
||||
return redirect(url_for("measure.select_recipe"))
|
||||
except Exception:
|
||||
return redirect(url_for("auth.profile"))
|
||||
# Redirect dopo login (in base al ruolo)
|
||||
return redirect(_post_login_landing())
|
||||
|
||||
except Exception as e:
|
||||
flash(_("Errore di connessione al server: %(error)s", error=str(e)), "error")
|
||||
|
||||
Reference in New Issue
Block a user