Make template rendering compatible across Starlette versions

This commit is contained in:
Krikorios
2026-05-07 13:05:24 +03:00
parent aed2fdc801
commit 68d13dbf57
6 changed files with 71 additions and 37 deletions
+34 -21
View File
@@ -1,6 +1,7 @@
from fastapi import APIRouter, Depends, Request, Form, HTTPException, status
from fastapi.responses import HTMLResponse, RedirectResponse, FileResponse
from fastapi.templating import Jinja2Templates
from services.template_utils import render_template
from services.auth_service import (
verify_password, get_user_by_username, create_user, delete_user, get_all_users,
create_session, get_session, delete_session, SESSION_TTL_SECONDS,
@@ -45,7 +46,7 @@ def require_admin(request: Request):
@router.get("/login", response_class=HTMLResponse)
async def login_get(request: Request):
return templates.TemplateResponse("login.html", {"request": request, "error": None})
return render_template(templates, request, "login.html", {"error": None})
@router.post("/login", response_class=HTMLResponse)
async def login_post(request: Request, username: str = Form(...), password: str = Form(...)):
@@ -53,18 +54,22 @@ async def login_post(request: Request, username: str = Form(...), password: str
ip = _client_ip(request)
if is_login_blocked(username, ip):
return templates.TemplateResponse(
return render_template(
templates,
request,
"login.html",
{"request": request, "error": "تم حجب محاولات تسجيل الدخول مؤقتاً. حاول بعد 15 دقيقة."},
{"error": "تم حجب محاولات تسجيل الدخول مؤقتاً. حاول بعد 15 دقيقة."},
status_code=429,
)
user = get_user_by_username(username)
if not user or not verify_password(user["password_hash"], password):
record_login_attempt(username, ip, success=False)
return templates.TemplateResponse(
return render_template(
templates,
request,
"login.html",
{"request": request, "error": "Invalid username or password"},
{"error": "Invalid username or password"},
status_code=401,
)
@@ -106,10 +111,7 @@ async def logout(request: Request):
@router.get("/users", response_class=HTMLResponse)
async def users_list(request: Request, current=Depends(require_admin)):
users = get_all_users()
return templates.TemplateResponse(
"users.html",
{"request": request, "users": users, "current_user": current},
)
return render_template(templates, request, "users.html", {"users": users, "current_user": current})
@router.post("/users/create")
async def add_user(
@@ -124,15 +126,19 @@ async def add_user(
role = "user"
if len(password) < 8:
users = get_all_users()
return templates.TemplateResponse(
return render_template(
templates,
request,
"users.html",
{"request": request, "users": users, "current_user": current, "error": "Password must be at least 8 characters."},
{"users": users, "current_user": current, "error": "Password must be at least 8 characters."},
)
if get_user_by_username(username):
users = get_all_users()
return templates.TemplateResponse(
return render_template(
templates,
request,
"users.html",
{"request": request, "users": users, "current_user": current, "error": f"User '{username}' already exists."},
{"users": users, "current_user": current, "error": f"User '{username}' already exists."},
)
create_user(username, password, role=role)
return RedirectResponse(url="/auth/users", status_code=status.HTTP_303_SEE_OTHER)
@@ -141,18 +147,22 @@ async def add_user(
async def remove_user(request: Request, user_id: int, current=Depends(require_admin)):
if user_id == current["user_id"]:
users = get_all_users()
return templates.TemplateResponse(
return render_template(
templates,
request,
"users.html",
{"request": request, "users": users, "current_user": current, "error": "لا يمكنك حذف حسابك الخاص."},
{"users": users, "current_user": current, "error": "لا يمكنك حذف حسابك الخاص."},
status_code=400,
)
# Prevent removing the last admin
target = next((u for u in get_all_users() if u["id"] == user_id), None)
if target and target["role"] == "admin" and count_admins() <= 1:
users = get_all_users()
return templates.TemplateResponse(
return render_template(
templates,
request,
"users.html",
{"request": request, "users": users, "current_user": current, "error": "لا يمكن حذف آخر مسؤول في النظام."},
{"users": users, "current_user": current, "error": "لا يمكن حذف آخر مسؤول في النظام."},
status_code=400,
)
delete_user(user_id)
@@ -172,9 +182,11 @@ async def change_role(
target = next((u for u in get_all_users() if u["id"] == user_id), None)
if target and target["role"] == "admin" and role != "admin" and count_admins() <= 1:
users = get_all_users()
return templates.TemplateResponse(
return render_template(
templates,
request,
"users.html",
{"request": request, "users": users, "current_user": current, "error": "لا يمكن تخفيض رتبة آخر مسؤول."},
{"users": users, "current_user": current, "error": "لا يمكن تخفيض رتبة آخر مسؤول."},
status_code=400,
)
set_user_role(user_id, role)
@@ -187,10 +199,11 @@ async def backup_db(request: Request, current=Depends(require_admin)):
return FileResponse(backup_path, media_type="application/octet-stream", filename=os.path.basename(backup_path))
except Exception as e:
msg = f"Backup failed: {str(e)}"
return templates.TemplateResponse(
return render_template(
templates,
request,
"users.html",
{
"request": request,
"users": get_all_users(),
"current_user": current,
"backup_msg": msg,