mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
from datetime import datetime
|
|
from fastapi import Depends, HTTPException, Request, status
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
from sqlalchemy.orm import Session
|
|
from utils import verify_token
|
|
from models import User, DeviceSession
|
|
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 |