start project

This commit is contained in:
Hemmat
2026-08-07 21:17:17 +03:30
commit ea1e1eead6
121 changed files with 8108 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
"""Single-admin auth routes (Chapter 12 / Chapter 11's route table)."""
from __future__ import annotations
from flask import flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required, login_user, logout_user
from app.blueprints.auth import bp
from app.blueprints.auth.forms import LoginForm
from app.extensions import db, limiter, login_manager
from app.models.user import User
@login_manager.user_loader
def load_user(user_id: str) -> User | None:
return db.session.get(User, int(user_id))
@bp.route("/login", methods=["GET", "POST"])
@limiter.limit("10 per minute") # Ch12: rate limiting on /login at minimum
def login():
if current_user.is_authenticated:
return redirect(url_for("overview.overview"))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data.strip().lower()).first()
if user is not None and user.check_password(form.password.data):
login_user(user)
next_url = request.args.get("next") or url_for("overview.overview")
return redirect(next_url)
flash("Invalid email or password.")
return render_template("auth/login.html", form=form)
@bp.post("/logout")
@login_required
def logout():
# NOTE (flagged): Ch11's route table lists "/login, /logout" under a
# shared "GET/POST" column. Logout is POST-only here — a state-changing
# action behind a plain GET is a CSRF-adjacent anti-pattern Ch12's own
# CSRF requirement argues against; login stays GET (show form) + POST
# (submit), matching the table as-is.
logout_user()
return redirect(url_for("auth.login"))