from datetime import datetime, timedelta, timezone import bcrypt import jwt from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from sqlalchemy.orm import Session from .config import settings from .database import get_db from .models import AdminUser oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/login") def hash_password(password: str) -> str: return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") def verify_password(password: str, hashed: str) -> bool: return bcrypt.checkpw(password.encode("utf-8"), hashed.encode("utf-8")) def create_access_token(username: str) -> str: expire = datetime.now(timezone.utc) + timedelta(minutes=settings.access_token_expire_minutes) payload = {"sub": username, "exp": expire} return jwt.encode(payload, settings.secret_key, algorithm=settings.algorithm) def get_current_admin( token: str = Depends(oauth2_scheme), db: Session = Depends(get_db), ) -> AdminUser: """وابستگی محافظت‌شده — فقط با توکن JWT معتبر دسترسی می‌دهد.""" credentials_error = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="احراز هویت نامعتبر است", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm]) except jwt.PyJWTError: raise credentials_error username = payload.get("sub") if not username: raise credentials_error user = db.query(AdminUser).filter(AdminUser.username == username).first() if user is None: raise credentials_error return user