File size: 2,431 Bytes
f9201f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
OAuth authentication utilities for HuggingFace token verification
"""
import requests
from typing import Optional, Dict

# HuggingFace OAuth userinfo endpoint
HF_USERINFO_URL = 'https://huggingface.co/oauth/userinfo'


def verify_hf_token(token: str) -> Optional[Dict]:
    """
    Verify HF OAuth token and return user info

    Args:
        token: The HuggingFace OAuth access token

    Returns:
        User info dict with fields: sub, preferred_username, name, picture, email
        None if token is invalid

    Example:
        {
            "sub": "12345678",
            "preferred_username": "username",
            "name": "Display Name",
            "picture": "https://avatars.huggingface.co/...",
            "email": "user@example.com"
        }
    """
    try:
        response = requests.get(
            HF_USERINFO_URL,
            headers={'Authorization': f'Bearer {token}'},
            timeout=10
        )

        if response.status_code == 200:
            return response.json()
        else:
            print(f"Token verification failed with status {response.status_code}")
            return None

    except requests.RequestException as e:
        print(f"Token verification error: {e}")
        return None


def extract_token_from_auth_header(auth_header: str) -> Optional[str]:
    """
    Extract Bearer token from Authorization header

    Args:
        auth_header: The Authorization header value (e.g., "Bearer abc123...")

    Returns:
        The token string, or None if invalid format
    """
    if not auth_header:
        return None

    if not auth_header.startswith('Bearer '):
        return None

    try:
        return auth_header.split(' ', 1)[1]
    except IndexError:
        return None


def get_user_from_request_headers(headers: Dict[str, str]) -> Optional[Dict]:
    """
    Extract and verify user info from request headers

    Args:
        headers: Dict of request headers (case-insensitive keys)

    Returns:
        User info dict if valid token, None otherwise
    """
    # Try to get Authorization header (case-insensitive)
    auth_header = None
    for key, value in headers.items():
        if key.lower() == 'authorization':
            auth_header = value
            break

    if not auth_header:
        return None

    token = extract_token_from_auth_header(auth_header)
    if not token:
        return None

    return verify_hf_token(token)