omyfish / apps /omyfish_api /auth.py
fenghebonjour's picture
Upload folder using huggingface_hub
3a7f77b verified
Raw
History Blame Contribute Delete
1.99 kB
from datetime import datetime, timedelta
from typing import Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import bcrypt
from jose import JWTError, jwt
from shared.config import settings
from shared.schemas.user import TokenData
_bearer = HTTPBearer(auto_error=False)
def hash_password(password: str) -> str:
return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
def verify_password(plain: str, hashed: str) -> bool:
return bcrypt.checkpw(plain.encode(), hashed.encode())
def create_access_token(user_id: str, role: str) -> str:
expire = datetime.utcnow() + timedelta(minutes=settings.jwt_expire_minutes)
return jwt.encode(
{"sub": user_id, "role": role, "exp": expire},
settings.jwt_secret,
algorithm=settings.jwt_algorithm,
)
def _decode(token: str) -> TokenData:
try:
payload = jwt.decode(token, settings.jwt_secret, algorithms=[settings.jwt_algorithm])
return TokenData(user_id=payload.get("sub"), role=payload.get("role"))
except JWTError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token")
def get_current_user(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(_bearer),
) -> TokenData:
if not credentials:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated")
return _decode(credentials.credentials)
def get_optional_user(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(_bearer),
) -> Optional[TokenData]:
if not credentials:
return None
try:
return _decode(credentials.credentials)
except HTTPException:
return None
def require_admin(user: TokenData = Depends(get_current_user)) -> TokenData:
if user.role != "admin":
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Admin only")
return user