Spaces:
Sleeping
Sleeping
File size: 3,063 Bytes
ed147e2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | """
Security 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 src.utils.config import settings
# Password hashing context using bcrypt
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(password: str) -> str:
"""
Hash a plain-text password using bcrypt.
Args:
password: Plain-text password to hash
Returns:
Hashed password string
Example:
>>> hashed = hash_password("my_secret_password")
>>> print(hashed)
$2b$12$...
"""
return pwd_context.hash(password)
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""
Verify a plain-text password against a hashed password.
Args:
plain_password: Plain-text password to verify
hashed_password: Hashed password to compare against
Returns:
True if password matches, False otherwise
Example:
>>> hashed = hash_password("my_password")
>>> verify_password("my_password", hashed)
True
>>> verify_password("wrong_password", hashed)
False
"""
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 claims to encode in the token (e.g., {"sub": "user@example.com"})
expires_delta: Optional custom expiration time
Returns:
Encoded JWT token string
Example:
>>> token = create_access_token({"sub": "user@example.com"})
>>> print(token)
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 access token.
Args:
token: JWT token string to decode
Returns:
Dictionary of claims if token is valid, None otherwise
Example:
>>> token = create_access_token({"sub": "user@example.com"})
>>> payload = decode_access_token(token)
>>> print(payload["sub"])
user@example.com
"""
try:
payload = jwt.decode(
token,
settings.secret_key,
algorithms=[settings.algorithm]
)
return payload
except JWTError:
return None
|