Source code for python_template_server.authentication_handler

"""Authentication handler for the server."""

import hashlib
import logging
import secrets

from template_python.logging_setup import setup_default_logging

from python_template_server.constants import ENV_FILE_PATH, TOKEN_ENV_VAR_NAME, TOKEN_LENGTH

setup_default_logging()
logger = logging.getLogger(__name__)


[docs] def generate_token() -> str: """Generate a secure random token. :return str: A URL-safe token string """ return secrets.token_urlsafe(TOKEN_LENGTH)
[docs] def hash_token(token: str) -> str: """Hash a token string using SHA-256. :param str token: The plain text token to hash :return str: The hexadecimal representation of the hashed token """ return hashlib.sha256(token.encode()).hexdigest()
[docs] def save_hashed_token(token: str) -> None: """Hash a token and save it to the .env file. :param str token: The plain text token to hash and save """ hashed = hash_token(token) if not ENV_FILE_PATH.exists(): ENV_FILE_PATH.touch() content = ENV_FILE_PATH.read_text() lines = content.splitlines(keepends=True) new_lines = [] for line in lines: if line.startswith(f"{TOKEN_ENV_VAR_NAME}="): new_lines.append(f"{TOKEN_ENV_VAR_NAME}={hashed}\n") else: new_lines.append(line) ENV_FILE_PATH.write_text("".join(new_lines))
[docs] def verify_token(token: str, hashed_token: str) -> bool: """Verify a token against the stored hash. :param str token: The plain text token to verify :param str hashed_token: The stored hashed token for comparison :return bool: True if the token matches the stored hash, False otherwise """ if not hashed_token: msg = "No stored token hash found for verification." raise ValueError(msg) return hash_token(token) == hashed_token
[docs] def generate_new_token() -> None: """Generate a new token, hash it, and save the hash to the .env file. This function generates a new secure random token, hashes it using SHA-256, and saves the hashed token to the .env file for future verification. """ new_token = generate_token() save_hashed_token(new_token) logger.info("New API token generated and saved.") print(f"Token: {new_token}") # Prevent logging token to log file