MedRAG / app /core /security.py
hetsheta's picture
Initial commit
ea50fb7
Raw
History Blame Contribute Delete
2.06 kB
from datetime import datetime, timedelta, timezone
from typing import Optional
import bcrypt
from jose import JWTError, jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from app.core.config import get_settings
settings = get_settings()
bearer_scheme = HTTPBearer()
def hash_password(plain: str) -> str:
return bcrypt.hashpw(plain.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")
def verify_password(plain: str, hashed: str) -> bool:
return bcrypt.checkpw(plain.encode("utf-8"), hashed.encode("utf-8"))
def _create_token(subject: str, kind: str, expires_delta: timedelta) -> str:
expire = datetime.now(timezone.utc) + expires_delta
payload = {"sub": subject, "kind": kind, "exp": expire, "iat": datetime.now(timezone.utc)}
return jwt.encode(payload, settings.secret_key, algorithm=settings.algorithm)
def create_access_token(user_id: str) -> str:
return _create_token(user_id, "access", timedelta(minutes=settings.access_token_expire_minutes))
def create_refresh_token(user_id: str) -> str:
return _create_token(user_id, "refresh", timedelta(days=settings.refresh_token_expire_days))
def decode_token(token: str) -> dict:
try:
return jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
except JWTError as exc:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
) from exc
def get_current_user_id(
credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
) -> str:
payload = decode_token(credentials.credentials)
if payload.get("kind") != "access":
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token type")
user_id: Optional[str] = payload.get("sub")
if not user_id:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token payload")
return user_id