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
|
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"])
|
@auth_bp.route("/login", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
"""Login page and form handler."""
|
"""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"):
|
if session.get("api_key"):
|
||||||
try:
|
return redirect(_post_login_landing())
|
||||||
return redirect(url_for("measure.select_recipe"))
|
|
||||||
except Exception:
|
|
||||||
return redirect(url_for("auth.profile"))
|
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
username = request.form.get("username", "").strip()
|
username = request.form.get("username", "").strip()
|
||||||
@@ -91,11 +108,8 @@ def login():
|
|||||||
|
|
||||||
flash(_("Benvenuto, %(name)s!", name=user.get("display_name", username)), "success")
|
flash(_("Benvenuto, %(name)s!", name=user.get("display_name", username)), "success")
|
||||||
|
|
||||||
# Redirect dopo login
|
# Redirect dopo login (in base al ruolo)
|
||||||
try:
|
return redirect(_post_login_landing())
|
||||||
return redirect(url_for("measure.select_recipe"))
|
|
||||||
except Exception:
|
|
||||||
return redirect(url_for("auth.profile"))
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
flash(_("Errore di connessione al server: %(error)s", error=str(e)), "error")
|
flash(_("Errore di connessione al server: %(error)s", error=str(e)), "error")
|
||||||
|
|||||||
Reference in New Issue
Block a user