File size: 2,579 Bytes
6ad61bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""

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)