from fastapi import Depends, HTTPException, Request, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from sqlalchemy.orm import Session from utils import * from models import * from db import SessionLocal security = HTTPBearer() # Зависимость для получения сессии БД def get_db(): db = SessionLocal() try: yield db finally: db.close() # Зависимость для получения текущего пользователя def get_current_user( request: Request, credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db), ) -> User: token = credentials.credentials payload = verify_token(token) if not payload: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token", headers={"WWW-Authenticate": "Bearer"}, ) user = db.query(User).filter(User.id == payload["user_id"]).first() if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found", headers={"WWW-Authenticate": "Bearer"}, ) if user.id == 1 and user.suspended: user.suspended = False user.suspension_reason = None db.commit() db.refresh(user) # Validate device session from JWT session_id = payload.get("session_id") if not session_id: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid session", headers={"WWW-Authenticate": "Bearer"}, ) device_session = ( db.query(DeviceSession) .filter(DeviceSession.user_id == user.id, DeviceSession.session_id == session_id) .first() ) if not device_session or device_session.revoked: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Session revoked or not found", headers={"WWW-Authenticate": "Bearer"}, ) # Touch last_seen on valid session device_session.last_seen = datetime.now() db.commit() # Check if user is suspended if user.suspended: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Account suspended", headers={"suspension_reason": user.suspension_reason or "No reason provided"}, ) # Check if user is deleted if user.deleted: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Account deleted", ) request.state.current_user = user request.state.session_id = session_id return user