RAG / backend /app /core /security.py
JenishMakwana's picture
Initial clean commit
69524c2
Raw
History Blame Contribute Delete
1.77 kB
from datetime import datetime, timedelta, timezone
# Reference: https://fastapi.tiangolo.com/tutorial/security/
from typing import Any, Union
from jose import jwt
import bcrypt
from passlib.context import CryptContext
from .config import settings
# Graceful legacy verifier for pbkdf2_sha256 hashes in database
legacy_context = CryptContext(schemes=["pbkdf2_sha256"])
def create_access_token(subject: Union[str, Any], expires_delta: timedelta = None) -> str:
# Use modern timezone-aware UTC datetime (Python 3.12+ standard)
now = datetime.now(timezone.utc)
if expires_delta:
expire = now + expires_delta
else:
expire = now + timedelta(
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
)
to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
return encoded_jwt
def verify_password(plain_password: str, hashed_password: str) -> bool:
try:
# If it's a legacy pbkdf2 hash, verify with passlib legacy context
if hashed_password.startswith("$pbkdf2-sha256"):
return legacy_context.verify(plain_password, hashed_password)
# Otherwise, verify using standard native bcrypt
return bcrypt.checkpw(
plain_password.encode("utf-8"),
hashed_password.encode("utf-8")
)
except Exception as e:
print(f"[-] Password verification error: {e}")
return False
def get_password_hash(password: str) -> str:
# Hash password using native bcrypt (highly secure and fully compatible with Python 3.12+)
pwd_bytes = password.encode("utf-8")
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(pwd_bytes, salt)
return hashed.decode("utf-8")