File size: 2,961 Bytes
31f0e50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
88
89
90
91
92
93
94
95
96
"""

API Key Authentication Module.



Provides middleware for validating x-api-key header as required by

the GUVI Hackathon submission requirements.



Requirement: "Participants must deploy a public API endpoint secured

with a user-provided API key."

"""

from typing import Optional

from fastapi import Request, HTTPException, Security
from fastapi.security import APIKeyHeader

from app.config import settings
from app.utils.logger import get_logger

logger = get_logger(__name__)

# Define the API key header
api_key_header = APIKeyHeader(name="x-api-key", auto_error=False)


async def verify_api_key(api_key: Optional[str] = Security(api_key_header)) -> str:
    """

    Verify the x-api-key header for API authentication.

    

    This is required for GUVI Hackathon submission compliance.

    The API key is provided by the participant and must be included

    in all requests to protected endpoints.

    

    Args:

        api_key: The API key from x-api-key header

        

    Returns:

        The validated API key

        

    Raises:

        HTTPException: 401 if API key is missing or invalid

    """
    # Skip authentication in development mode
    if settings.is_development:
        logger.debug("Development mode, skipping API key validation")
        return api_key or "dev-mode"
    
    # If API key is not configured, skip authentication
    if not settings.API_KEY:
        logger.warning("API_KEY not configured, skipping authentication")
        return "no-auth"
    
    if not api_key:
        logger.warning("Request missing x-api-key header")
        raise HTTPException(
            status_code=401,
            detail={
                "code": "MISSING_API_KEY",
                "message": "Missing x-api-key header. API key is required for authentication.",
            },
            headers={"WWW-Authenticate": "ApiKey"},
        )
    
    if api_key != settings.API_KEY:
        logger.warning(f"Invalid API key provided: {api_key[:8]}...")
        raise HTTPException(
            status_code=401,
            detail={
                "code": "INVALID_API_KEY",
                "message": "Invalid API key. Please provide a valid x-api-key header.",
            },
            headers={"WWW-Authenticate": "ApiKey"},
        )
    
    logger.debug("API key validated successfully")
    return api_key


async def optional_api_key(api_key: Optional[str] = Security(api_key_header)) -> Optional[str]:
    """

    Optional API key validation for endpoints that support both authenticated

    and unauthenticated access.

    

    Args:

        api_key: The API key from x-api-key header (optional)

        

    Returns:

        The API key if provided and valid, None otherwise

    """
    if not api_key:
        return None
    
    if settings.API_KEY and api_key == settings.API_KEY:
        return api_key
    
    return None