Files
authsec_firstAPI/app/core/security.py
T

59 lines
2.1 KiB
Python
Raw Normal View History

2026-10-25 23:11:19 +05:30
import hashlib
import secrets
from datetime import datetime, timedelta
from typing import Optional, Any, Union
import jwt
from app.core.config import settings
def get_password_hash(password: str) -> str:
"""
Hashes a password with PBKDF2-HMAC-SHA256 using Python's standard library.
Requires NO C compilers or external dependencies.
"""
salt = secrets.token_hex(16)
key = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt.encode("utf-8"), 100000)
return f"pbkdf2:sha256:100000${salt}${key.hex()}"
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verifies a plain password against the stored hash."""
if not hashed_password:
return False
if "$" not in hashed_password:
# Fallback comparison for plain text
return plain_password == hashed_password
try:
parts = hashed_password.split("$")
if len(parts) == 3 and parts[0].startswith("pbkdf2:"):
_, salt, key_hex = parts
check_key = hashlib.pbkdf2_hmac("sha256", plain_password.encode("utf-8"), salt.encode("utf-8"), 100000)
return secrets.compare_digest(check_key.hex(), key_hex)
return plain_password == hashed_password
except Exception:
return False
def create_access_token(subject: Union[str, Any], expires_delta: Optional[timedelta] = None, extra_claims: Optional[dict] = None) -> str:
"""Creates a signed JWT token."""
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode = {
"exp": expire,
"sub": str(subject),
"user_id": subject
}
if extra_claims:
to_encode.update(extra_claims)
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
return encoded_jwt
def decode_access_token(token: str) -> Optional[dict]:
"""Decodes a JWT token."""
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
return payload
except Exception:
return None