mirror of
https://github.com/home-assistant/core.git
synced 2026-07-14 10:03:52 +01:00
37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
"""Authentication helper classes for the Model Context Protocol integration."""
|
|
|
|
from dataclasses import dataclass
|
|
import re
|
|
|
|
import httpx
|
|
from yarl import URL
|
|
|
|
# Headers and regex for WWW-Authenticate parsing for rfc9728
|
|
WWW_AUTHENTICATE_HEADER = "WWW-Authenticate"
|
|
RESOURCE_METADATA_REGEXP = r'resource_metadata="([^"]+)"'
|
|
SCOPES_REGEXP = r'scope="([^"]+)"'
|
|
|
|
|
|
@dataclass
|
|
class AuthenticateHeader:
|
|
"""Class to hold info from the WWW-Authenticate header for supporting rfc9728."""
|
|
|
|
resource_metadata_url: str
|
|
scopes: list[str] | None = None
|
|
|
|
@classmethod
|
|
def from_header(
|
|
cls, url: str, error_response: httpx.Response
|
|
) -> AuthenticateHeader | None:
|
|
"""Create AuthenticateHeader from WWW-Authenticate header."""
|
|
if not (header := error_response.headers.get(WWW_AUTHENTICATE_HEADER)) or not (
|
|
match := re.search(RESOURCE_METADATA_REGEXP, header)
|
|
):
|
|
return None
|
|
resource_metadata_url = str(URL(url).join(URL(match.group(1))))
|
|
scope_match = re.search(SCOPES_REGEXP, header)
|
|
return cls(
|
|
resource_metadata_url=resource_metadata_url,
|
|
scopes=scope_match.group(1).split(" ") if scope_match else None,
|
|
)
|