CytoSight / backend /app /utils /auth.py
Kaifulimaan's picture
Deployment without binary files
894fa47
"""
Authentication utilities for password hashing and JWT token management.
"""
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from passlib.context import CryptContext
from app.config import settings
# Password hashing context
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(password: str) -> str:
"""
Hash a plain password using bcrypt.
Args:
password: Plain text password
Returns:
Hashed password string
Example:
>>> hash_password("mypassword123")
'$2b$12$KIXqZ9Zu8...'
"""
return pwd_context.hash(password)
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""
Verify a plain password against a hashed password.
Args:
plain_password: Password entered by user
hashed_password: Hashed password from database
Returns:
True if password matches, False otherwise
Example:
>>> verify_password("mypassword123", "$2b$12$KIXqZ9Zu8...")
True
"""
return pwd_context.verify(plain_password, hashed_password)
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
"""
Create a JWT access token.
Args:
data: Dictionary of data to encode in token (usually user_id and email)
expires_delta: Optional custom expiration time
Returns:
Encoded JWT token string
Example:
>>> create_access_token({"sub": "user-id", "email": "user@example.com"})
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
"""
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=settings.access_token_expire_minutes)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, settings.secret_key, algorithm=settings.algorithm)
return encoded_jwt
def decode_access_token(token: str) -> Optional[dict]:
"""
Decode and verify a JWT token.
Args:
token: JWT token string
Returns:
Decoded token data if valid, None if invalid
Example:
>>> decode_access_token("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
{'sub': 'user-id', 'email': 'user@example.com', 'exp': 1234567890}
"""
try:
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
return payload
except JWTError:
return None