Hamza4100's picture
Upload 7 files
6ad61bb verified
"""
API Authentication Module
=========================
Implements API key-based authentication for the FastAPI backend.
"""
import os
import hashlib
from typing import Optional
from fastapi import Header, HTTPException, status
class AuthManager:
"""Manages API key authentication and user identification."""
def __init__(self):
"""Initialize auth manager with API keys from environment."""
api_keys_str = os.environ.get("API_KEYS", "")
self.valid_api_keys = set(
key.strip() for key in api_keys_str.split(",") if key.strip()
)
if not self.valid_api_keys:
print("⚠️ WARNING: No API keys configured! Set API_KEYS environment variable.")
else:
print(f"✅ Auth Manager initialized with {len(self.valid_api_keys)} API key(s)")
def derive_user_id(self, api_key: str) -> str:
"""
Derive a stable user ID from API key using SHA256.
Args:
api_key: The API key
Returns:
12-character user ID derived from key hash
"""
hash_bytes = hashlib.sha256(api_key.encode()).digest()
return hash_bytes.hex()[:12]
def validate_api_key(self, api_key: Optional[str]) -> str:
"""
Validate API key and return user ID.
Args:
api_key: API key from request header
Returns:
user_id: Derived user identifier
Raises:
HTTPException: If API key is invalid or missing
"""
if not api_key:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Missing X-API-KEY header"
)
if api_key not in self.valid_api_keys:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API key"
)
return self.derive_user_id(api_key)
# Global auth manager instance
auth_manager = AuthManager()
async def get_current_user(x_api_key: Optional[str] = Header(None, alias="X-API-KEY")) -> str:
"""
FastAPI dependency for extracting authenticated user ID.
Args:
x_api_key: API key from X-API-KEY header
Returns:
user_id: Authenticated user identifier
Raises:
HTTPException: If authentication fails
"""
return auth_manager.validate_api_key(x_api_key)