Coverage for src/lexigram/auth/web/middleware/api_key_authenticator.py: 48%
21 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 00:58 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 00:58 +0800
1"""API key authentication component."""
3from __future__ import annotations
5from typing import Any
7from lexigram.contracts import AuthProviderProtocol
10class ApiKeyAuthenticator:
11 """Handles API key validation and user resolution."""
13 def __init__(self, auth_provider: AuthProviderProtocol):
14 self.auth_provider = auth_provider
16 async def authenticate(self, token: str, request: Any) -> Any:
17 """Validate API key and return user if valid."""
18 if not token.startswith("sk_"):
19 return None
21 if not self.auth_provider.api_key_manager:
22 return None
24 api_key = await self.auth_provider.api_key_manager.validate_key(
25 token,
26 ip_address=getattr(request.client, "host", None),
27 )
28 if not api_key or not api_key.user_id:
29 return None
31 user = await self.auth_provider.get_user(api_key.user_id)
32 if not user:
33 return None
35 # Pre-fetch delegations for sync check_access
36 if self.auth_provider.delegation_manager:
37 request.state.delegations = (
38 await self.auth_provider.delegation_manager.get_active_delegations(
39 user.user_id,
40 )
41 )
43 return user
46__all__ = [
47 "ApiKeyAuthenticator",
48]