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