Files
evo-sync/web/routes/profile.py

145 lines
4.6 KiB
Python
Raw Normal View History

from fastapi import APIRouter, Request, Depends
from fastapi.responses import RedirectResponse
from web.templates_env import templates
from sqlalchemy.orm import Session
from web.auth import get_current_user, verify_password, hash_password
from web.database import get_db
from web.models import User
from web.schemas import validate_profile, validate_reset_password
router = APIRouter()
# VIEW PROFILE
@router.get("/profile")
def profile_view(request: Request, user: User | None = Depends(get_current_user)):
if not user:
return RedirectResponse("/login", 303)
return templates.TemplateResponse("profile_view.html", {"request": request, "user": user})
# EDIT PROFILE
@router.get("/profile/edit")
def profile_edit_form(request: Request, user: User | None = Depends(get_current_user)):
if not user:
return RedirectResponse("/login", 303)
return templates.TemplateResponse("profile_edit.html", {"request": request, "user": user})
@router.post("/profile/edit")
async def profile_edit_submit(
request: Request,
db: Session = Depends(get_db),
user: User | None = Depends(get_current_user),
):
if not user:
return RedirectResponse("/login", 303)
form = await request.form()
data = dict(form)
errors = validate_profile(data)
if not errors:
existing = db.query(User).filter(
User.phone == data["phone"].strip(), User.id != user.id
).first()
if existing:
errors.append("Пользователь с таким телефоном уже существует")
if errors:
return templates.TemplateResponse("profile_edit.html", {
"request": request, "user": user, "errors": errors, "form": data,
})
user.first_name = data["first_name"].strip()
user.last_name = data["last_name"].strip()
user.phone = data["phone"].strip()
db.commit()
return templates.TemplateResponse("profile_edit.html", {
"request": request, "user": user, "success": "Профиль обновлен",
})
# CHANGE PASSWORD
@router.get("/profile/change-password")
def change_password_form(request: Request, user: User | None = Depends(get_current_user)):
if not user:
return RedirectResponse("/login", 303)
return templates.TemplateResponse("profile_change_password.html", {"request": request, "user": user})
@router.post("/profile/change-password")
async def change_password_submit(
request: Request,
db: Session = Depends(get_db),
user: User | None = Depends(get_current_user),
):
if not user:
return RedirectResponse("/login", 303)
form = await request.form()
data = dict(form)
errors = []
current_password = data.get("current_password", "")
if not current_password:
errors.append("Введите текущий пароль")
elif not verify_password(current_password, user.password_hash):
errors.append("Неверный текущий пароль")
password_errors = validate_reset_password(data)
errors.extend(password_errors)
if errors:
return templates.TemplateResponse("profile_change_password.html", {
"request": request, "user": user, "errors": errors,
})
user.password_hash = hash_password(data["password"])
db.commit()
return templates.TemplateResponse("profile_change_password.html", {
"request": request, "user": user, "success": "Пароль изменен",
})
# DELETE ACCOUNT
@router.get("/profile/delete")
def delete_account_form(request: Request, user: User | None = Depends(get_current_user)):
if not user:
return RedirectResponse("/login", 303)
return templates.TemplateResponse("profile_delete.html", {"request": request, "user": user})
@router.post("/profile/delete")
async def delete_account_submit(
request: Request,
db: Session = Depends(get_db),
user: User | None = Depends(get_current_user),
):
if not user:
return RedirectResponse("/login", 303)
form = await request.form()
data = dict(form)
password = data.get("password", "")
if not password:
return templates.TemplateResponse("profile_delete.html", {
"request": request, "user": user, "errors": ["Введите пароль для подтверждения"],
})
if not verify_password(password, user.password_hash):
return templates.TemplateResponse("profile_delete.html", {
"request": request, "user": user, "errors": ["Неверный пароль"],
})
db.delete(user)
db.commit()
request.session.clear()
return RedirectResponse("/", 303)