1 """Handle the auth of a connection."""
3 from __future__
import annotations
5 from collections.abc
import Callable, Coroutine
6 from typing
import TYPE_CHECKING, Any, Final
8 from aiohttp.web
import Request
9 import voluptuous
as vol
10 from voluptuous.humanize
import humanize_error
18 from .connection
import ActiveConnection
19 from .error
import Disconnect
22 from .http
import WebSocketAdapter
25 TYPE_AUTH: Final =
"auth"
26 TYPE_AUTH_INVALID: Final =
"auth_invalid"
27 TYPE_AUTH_OK: Final =
"auth_ok"
28 TYPE_AUTH_REQUIRED: Final =
"auth_required"
30 AUTH_MESSAGE_SCHEMA: Final = vol.Schema(
32 vol.Required(
"type"): TYPE_AUTH,
33 vol.Exclusive(
"api_password",
"auth"): str,
34 vol.Exclusive(
"access_token",
"auth"): str,
38 AUTH_OK_MESSAGE =
json_bytes({
"type": TYPE_AUTH_OK,
"ha_version": __version__})
40 {
"type": TYPE_AUTH_REQUIRED,
"ha_version": __version__}
45 """Return an auth_invalid message."""
46 return json_bytes({
"type": TYPE_AUTH_INVALID,
"message": message})
50 """Connection that requires client to authenticate first."""
54 logger: WebSocketAdapter,
56 send_message: Callable[[bytes | str | dict[str, Any]],
None],
57 cancel_ws: CALLBACK_TYPE,
59 send_bytes_text: Callable[[bytes], Coroutine[Any, Any,
None]],
61 """Initialize the authenticated connection."""
71 async
def async_handle(self, msg: JsonValueType) -> ActiveConnection:
72 """Handle authentication."""
74 valid_msg = AUTH_MESSAGE_SCHEMA(msg)
75 except vol.Invalid
as err:
77 f
"Auth message incorrectly formatted: {humanize_error(msg, err)}"
79 self.
_logger_logger.warning(error_msg)
81 raise Disconnect
from err
83 if (access_token := valid_msg.get(
"access_token"))
and (
84 refresh_token := self.
_hass_hass.auth.async_validate_access_token(access_token)
93 conn.subscriptions[
"auth"] = (
94 self.
_hass_hass.auth.async_register_revoke_token_callback(
99 self.
_logger_logger.debug(
"Auth OK")
ActiveConnection async_handle(self, JsonValueType msg)
None __init__(self, WebSocketAdapter logger, HomeAssistant hass, Callable[[bytes|str|dict[str, Any]], None] send_message, CALLBACK_TYPE cancel_ws, Request request, Callable[[bytes], Coroutine[Any, Any, None]] send_bytes_text)
None process_wrong_login(Request request)
None process_success_login(Request request)
bytes auth_invalid_message(str message)