| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- from datetime import datetime, timedelta, timezone
- from typing import Optional
- import bcrypt
- import jwt
- from fastapi import Depends, HTTPException, status
- from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
- from sqlalchemy import select
- from sqlalchemy.ext.asyncio import AsyncSession
- from .config import get_settings
- from .database import get_db
- from .models import Admin
- security = HTTPBearer()
- def hash_password(password: str) -> str:
- return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
- def verify_password(password: str, hashed: str) -> bool:
- return bcrypt.checkpw(password.encode(), hashed.encode())
- def create_token(admin_id: int, username: str) -> str:
- settings = get_settings()
- expire = datetime.now(timezone.utc) + timedelta(hours=settings.jwt_expire_hours)
- payload = {"sub": str(admin_id), "username": username, "exp": expire}
- return jwt.encode(payload, settings.jwt_secret, algorithm=settings.jwt_algorithm)
- def decode_token(token: str) -> Optional[dict]:
- settings = get_settings()
- try:
- return jwt.decode(token, settings.jwt_secret, algorithms=[settings.jwt_algorithm])
- except jwt.PyJWTError:
- return None
- async def get_current_admin(
- credentials: HTTPAuthorizationCredentials = Depends(security),
- db: AsyncSession = Depends(get_db),
- ) -> Admin:
- payload = decode_token(credentials.credentials)
- if not payload:
- raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
- admin_id = int(payload.get("sub", 0))
- result = await db.execute(select(Admin).where(Admin.id == admin_id, Admin.is_active == True))
- admin = result.scalar_one_or_none()
- if not admin:
- raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Admin not found")
- return admin
|