RM / app\core\security.py
Bromeo777's picture
Add app\core\security.py
8f3856f verified
import secrets
from datetime import datetime, timedelta, timezone
from typing import Any, Union, Optional
from jose import jwt
from passlib.context import CryptContext
from app.core.config import settings
# ------------------------------------------------------------------
# Cryptographic Context
# ------------------------------------------------------------------
# Standardizing on bcrypt for secure password hashing.
# It includes internal salting and a configurable work factor to resist brute-force.
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# ------------------------------------------------------------------
# JWT Orchestration
# ------------------------------------------------------------------
def create_access_token(
subject: Union[str, Any],
expires_delta: Optional[timedelta] = None
) -> str:
"""
Generates a secure JWT access token for user sessions.
Security Hardening:
- Includes 'iss' (Issuer) to verify the token origin.
- Includes 'aud' (Audience) to restrict token usage to specific services.
- Enforces UTC expiration to prevent regional clock-skew issues.
"""
if expires_delta:
expire = datetime.now(timezone.utc) + expires_delta
else:
expire = datetime.now(timezone.utc) + timedelta(
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
)
# Payload claims aligned with RFC 7519 standards
to_encode = {
"exp": expire,
"sub": str(subject),
"iss": settings.JWT_ISSUER,
"aud": settings.JWT_AUDIENCE
}
encoded_jwt = jwt.encode(
to_encode,
settings.SECRET_KEY,
algorithm=settings.ALGORITHM
)
return encoded_jwt
# ------------------------------------------------------------------
# Password & Hashing Utilities
# ------------------------------------------------------------------
def generate_random_password() -> str:
"""
Generates a high-entropy, cryptographically secure random password.
Primary use: Temporary credentials for users provisioned via SSO/SAML.
"""
return secrets.token_urlsafe(16)
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""
Verifies a plain-text password against the stored bcrypt hash.
Standard protection against timing attacks.
"""
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password: str) -> str:
"""
Hashes a password using the bcrypt algorithm.
Automatically handles salt generation and storage.
"""
return pwd_context.hash(password)