| """ |
| HuggingFace Space Authentication |
| Authentication middleware for HuggingFace Space API endpoints |
| |
| CRITICAL RULES: |
| - Verify HF_TOKEN from environment |
| - Return error if token missing or invalid |
| - NO bypass - authentication is REQUIRED |
| """ |
|
|
| import os |
| import logging |
| from fastapi import Security, HTTPException, status, Header |
| from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials |
| from typing import Optional |
|
|
| logger = logging.getLogger(__name__) |
|
|
| |
| HF_TOKEN_ENV = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACE_TOKEN") |
|
|
| |
| TEST_MODE = os.getenv("TEST_MODE", "false").lower() == "true" |
|
|
| if TEST_MODE: |
| logger.warning("=" * 80) |
| logger.warning("🧪 TEST MODE ACTIVE - Authentication bypass enabled!") |
| logger.warning(" Set TEST_MODE=false in production") |
| logger.warning("=" * 80) |
|
|
| |
| security = HTTPBearer(auto_error=False) |
|
|
|
|
| async def verify_hf_token( |
| credentials: Optional[HTTPAuthorizationCredentials] = Security(security), |
| authorization: Optional[str] = Header(None) |
| ) -> bool: |
| """ |
| Verify HuggingFace API token |
| |
| CRITICAL RULES: |
| 1. MUST check credentials from Bearer token OR Authorization header |
| 2. MUST compare with HF_TOKEN from environment |
| 3. MUST return 401 if token missing or invalid |
| 4. NO fake authentication - REAL token verification ONLY |
| |
| Args: |
| credentials: HTTP Bearer token credentials |
| authorization: Authorization header (fallback) |
| |
| Returns: |
| bool: True if authenticated |
| |
| Raises: |
| HTTPException: 401 if authentication fails |
| """ |
| |
| |
| provided_token = None |
| |
| if credentials: |
| provided_token = credentials.credentials |
| elif authorization: |
| |
| if authorization.startswith("Bearer "): |
| provided_token = authorization[7:] |
| else: |
| provided_token = authorization |
| |
| |
| if TEST_MODE: |
| logger.info("✅ TEST MODE: Authentication bypassed") |
| return { |
| "user_id": "test_user", |
| "username": "test_user", |
| "test_mode": True, |
| "access_level": "full", |
| "note": "TEST_MODE active - no real authentication" |
| } |
| |
| |
| if not provided_token: |
| logger.warning("Authentication failed: No token provided") |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail={ |
| "success": False, |
| "error": "Authentication required. Please provide HF_TOKEN in Authorization header.", |
| "source": "hf_engine", |
| "hint": "For development: Set TEST_MODE=true in .env" |
| }, |
| headers={"WWW-Authenticate": "Bearer"} |
| ) |
| |
| |
| if not HF_TOKEN_ENV: |
| logger.error("HF_TOKEN not configured in environment") |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail={ |
| "success": False, |
| "error": "HF_TOKEN not configured on server. Please set HF_TOKEN environment variable.", |
| "source": "hf_engine" |
| } |
| ) |
| |
| |
| |
| if provided_token != HF_TOKEN_ENV: |
| logger.warning(f"Authentication failed: Invalid token provided (length: {len(provided_token)})") |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail={ |
| "success": False, |
| "error": "Invalid authentication token", |
| "source": "hf_engine" |
| }, |
| headers={"WWW-Authenticate": "Bearer"} |
| ) |
| |
| |
| logger.info("Authentication successful") |
| return True |
|
|
|
|
| async def optional_hf_token( |
| credentials: Optional[HTTPAuthorizationCredentials] = Security(security), |
| authorization: Optional[str] = Header(None) |
| ) -> Optional[bool]: |
| """ |
| Optional HF token verification (for endpoints that can work without auth) |
| |
| Returns: |
| Optional[bool]: True if authenticated, None if no token provided |
| """ |
| try: |
| return await verify_hf_token(credentials, authorization) |
| except HTTPException: |
| |
| return None |
|
|