Source code for modules.utils.token

from bson import ObjectId
from datetime import datetime, timedelta, timezone
from dotenv import load_dotenv 
from os import getenv
from typing import Any, Dict
from modules.utils.log import Log
import jwt

load_dotenv()

[docs] class Token: """ Controls the JWT in the app. Args: __JWT_SECRET_KEY (str): The key to hash the JWT. __JWT_ALGORITHM (str): The JWT algorithm. Defaults to "HS256". __JWT_EXPIRATION (int): The valid time of the token. """ __JWT_SECRET_KEY: str = getenv("JWT_SECRET_KEY") or "" __JWT_ALGORITHM: str = getenv("JWT_ALGORITHM", "HS256") __JWT_EXPIRATION: int = int(getenv("JWT_EXPIRATION", 1)) if not __JWT_SECRET_KEY: raise ValueError("JWT_SECRET_KEY isn't configured in the env.") @classmethod def __decode(cls, token: str) -> Dict[str, Any]: """ Decode a JWT. Args: token (str): The JWT token to decode. Raises: RuntimeError: Error decoding the token. Returns: Dict[str, Any]: Token info or {}. """ try: return jwt.decode(token, cls.__JWT_SECRET_KEY, algorithms=[cls.__JWT_ALGORITHM]) except jwt.ExpiredSignatureError: pass except jwt.InvalidTokenError: Log.error(f"Invalid Token: {token}.") pass except Exception as e: raise RuntimeError(f"Error decodifing the token: {e}") from e return {}
[docs] @classmethod def encode(cls, user_id: ObjectId, username: str) -> str: """ Encode a token. Args: user_id (ObjectId): The user's ID. username (str): The user's username. Raises: RuntimeError: If it can't be encoded. Returns: str: The JWT token. """ try: payload: Dict[str, Any] = { "_id": str(user_id), "username": str(username), "exp": datetime.now(timezone.utc) + timedelta(days=cls.__JWT_EXPIRATION) } return jwt.encode(payload, cls.__JWT_SECRET_KEY, algorithm=cls.__JWT_ALGORITHM) except Exception as e: raise RuntimeError(f"Error codifing the token: {e}") from e
[docs] @classmethod def is_valid(cls, token: str) -> Dict[str, Any]: """ Verify a JWT. Args: token (str): The token to verify. Raises: RuntimeError: If the token can't be validate. Returns: Dict[str, Any]: {"verify": True, "user": (token info)} or {"verify": False, "error": (error)} """ try: if not token: return {"verify": False, "error": "Required token"} decoded_token: Dict[str, Any] = cls.__decode(token) if decoded_token: user_data: Dict[str, Any] = {k: v for k, v in decoded_token.items() if k != "exp"} return {"verify": True, "user": user_data} #agregar token caduco return {"verify": False, "error": "Invalid token"} except Exception as e: raise RuntimeError(f"Error validating the token: {e}") from e